[oe] [PATCH] Add support for the Technologic Systems TS7500 ARM SBCs

UDel V2G Team v2g.udel at gmail.com
Tue Mar 29 21:46:39 UTC 2011


From: Sachin Kamboj <skamboj at udel.edu>

* Includes conf/machine/ts75xx.conf and conf/machine/include/tune-fa526.inc
  files needed for building OE packages w/ EABI and *NO* thumb support
* Adds recipes for building TS75xx userspace utilities:
  canctl, dioctl, dmxctl, jed2vme, sdctl, ts7500ctl,  spiflashctl and xuartctl
* Adds a custom kernel with all the patches for the Cavium FA 526 core
* Added a busybox defconfig for building a version of busybox that will be
  very similar to the shipped version
* Added two images - one for building the initrd image and the other for
  building the rootfs image.

Signed-off-by: UDel V2G Team <v2g.udel at gmail.com>
---
 conf/distro/include/angstrom.inc                   |    2 +-
 conf/machine/include/tune-fa526.inc                |   23 +
 conf/machine/ts75xx.conf                           |   22 +
 files/device_table-ts75xx.txt                      |   66 +
 recipes/busybox/busybox-1.13.2/ts75xx/defconfig    |  986 +
 recipes/busybox/busybox-1.18.3/ts75xx/defconfig    |  986 +
 recipes/images/ts75xx-initrd-image.bb              |   89 +
 recipes/images/ts75xx-rootfs-image.bb              |  206 +
 .../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 +
 recipes/nbd/files/nbd.h                            |  102 +
 recipes/nbd/nbd_2.8.7.bb.changed                   |   31 +
 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 +
 33 files changed, 104717 insertions(+), 1 deletions(-)
 create mode 100755 conf/machine/include/tune-fa526.inc
 create mode 100755 conf/machine/ts75xx.conf
 create mode 100644 files/device_table-ts75xx.txt
 create mode 100644 recipes/busybox/busybox-1.13.2/ts75xx/defconfig
 create mode 100644 recipes/busybox/busybox-1.18.3/ts75xx/defconfig
 create mode 100644 recipes/images/ts75xx-initrd-image.bb
 create mode 100644 recipes/images/ts75xx-rootfs-image.bb
 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
 create mode 100644 recipes/nbd/files/nbd.h
 create mode 100644 recipes/nbd/nbd_2.8.7.bb.changed
 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/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
diff --git a/conf/machine/include/tune-fa526.inc b/conf/machine/include/tune-fa526.inc
new file mode 100755
index 0000000..33bac22
--- /dev/null
+++ b/conf/machine/include/tune-fa526.inc
@@ -0,0 +1,23 @@
+# 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
+# (http://www.mail-archive.com/openocd-development <at> lists.berlios.de/msg05856.html)
+#
+# 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
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/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
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
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 at 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 at 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 at willothewisp.demon.co.uk)
++ *  nommu support by Hyok S. Choi (hyok.choi at samsung.com)
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  Low-level vector interface routines
++ *
++ *  Note:  there is a StrongARM bug in the STMIA rn, {regs}^ instruction
++ *  that causes it to save wrong values...  Be aware!
++ */
++
++#include <asm/memory.h>
++#include <asm/glue.h>
++#include <asm/vfpmacros.h>
++#include <mach/entry-macro.S>
++#include <asm/thread_notify.h>
++#include <asm/unwind.h>
++#include <asm/unistd.h>
++
++#include "entry-header.S"
++
++/*
++ * Interrupt handling.  Preserves r7, r8, r9
++ */
++	.macro	irq_handler
++	get_irqnr_preamble r5, lr
++1:	get_irqnr_and_base r0, r6, r5, lr
++	movne	r1, sp
++	@
++	@ routine called with r0 = irq number, r1 = struct pt_regs *
++	@
++	adrne	lr, BSYM(1b)
++	bne	asm_do_IRQ
++
++#ifdef CONFIG_SMP
++	/*
++	 * XXX
++	 *
++	 * this macro assumes that irqstat (r6) and base (r5) are
++	 * preserved from get_irqnr_and_base above
++	 */
++	test_for_ipi r0, r6, r5, lr
++	movne	r0, sp
++	adrne	lr, BSYM(1b)
++	bne	do_IPI
++
++#ifdef CONFIG_LOCAL_TIMERS
++	test_for_ltirq r0, r6, r5, lr
++	movne	r0, sp
++	adrne	lr, BSYM(1b)
++	bne	do_local_timer
++#endif
++#endif
++
++	.endm
++
++#ifdef CONFIG_KPROBES
++	.section	.kprobes.text,"ax",%progbits
++#else
++	.text
++#endif
++
++/*
++ * Invalid mode handlers
++ */
++	.macro	inv_entry, reason
++	sub	sp, sp, #S_FRAME_SIZE
++ ARM(	stmib	sp, {r1 - lr}		)
++ THUMB(	stmia	sp, {r0 - r12}		)
++ THUMB(	str	sp, [sp, #S_SP]		)
++ THUMB(	str	lr, [sp, #S_LR]		)
++	mov	r1, #\reason
++	.endm
++
++__pabt_invalid:
++	inv_entry BAD_PREFETCH
++	b	common_invalid
++ENDPROC(__pabt_invalid)
++
++__dabt_invalid:
++	inv_entry BAD_DATA
++	b	common_invalid
++ENDPROC(__dabt_invalid)
++
++__irq_invalid:
++	inv_entry BAD_IRQ
++	b	common_invalid
++ENDPROC(__irq_invalid)
++
++__und_invalid:
++	inv_entry BAD_UNDEFINSTR
++
++	@
++	@ XXX fall through to common_invalid
++	@
++
++@
++@ common_invalid - generic code for failed exception (re-entrant version of handlers)
++@
++common_invalid:
++	zero_fp
++
++	ldmia	r0, {r4 - r6}
++	add	r0, sp, #S_PC		@ here for interlock avoidance
++	mov	r7, #-1			@  ""   ""    ""        ""
++	str	r4, [sp]		@ save preserved r0
++	stmia	r0, {r5 - r7}		@ lr_<exception>,
++					@ cpsr_<exception>, "old_r0"
++
++	mov	r0, sp
++	b	bad_mode
++ENDPROC(__und_invalid)
++
++/*
++ * SVC mode handlers
++ */
++
++#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
++#define SPFIX(code...) code
++#else
++#define SPFIX(code...)
++#endif
++
++	.macro	svc_entry, stack_hole=0
++ UNWIND(.fnstart		)
++ UNWIND(.save {r0 - pc}		)
++	sub	sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)
++#ifdef CONFIG_THUMB2_KERNEL
++ SPFIX(	str	r0, [sp]	)	@ temporarily saved
++ SPFIX(	mov	r0, sp		)
++ SPFIX(	tst	r0, #4		)	@ test original stack alignment
++ SPFIX(	ldr	r0, [sp]	)	@ restored
++#else
++ SPFIX(	tst	sp, #4		)
++#endif
++ SPFIX(	subeq	sp, sp, #4	)
++	stmia	sp, {r1 - r12}
++
++	ldmia	r0, {r1 - r3}
++	add	r5, sp, #S_SP - 4	@ here for interlock avoidance
++	mov	r4, #-1			@  ""  ""      ""       ""
++	add	r0, sp, #(S_FRAME_SIZE + \stack_hole - 4)
++ SPFIX(	addeq	r0, r0, #4	)
++	str	r1, [sp, #-4]!		@ save the "real" r0 copied
++					@ from the exception stack
++
++	mov	r1, lr
++
++	@
++	@ We are now ready to fill in the remaining blanks on the stack:
++	@
++	@  r0 - sp_svc
++	@  r1 - lr_svc
++	@  r2 - lr_<exception>, already fixed up for correct return/restart
++	@  r3 - spsr_<exception>
++	@  r4 - orig_r0 (see pt_regs definition in ptrace.h)
++	@
++	stmia	r5, {r0 - r4}
++	.endm
++
++	.align	5
++__dabt_svc:
++	svc_entry
++
++	@
++	@ get ready to re-enable interrupts if appropriate
++	@
++	mrs	r9, cpsr
++	tst	r3, #PSR_I_BIT
++	biceq	r9, r9, #PSR_I_BIT
++
++	@
++	@ Call the processor-specific abort handler:
++	@
++	@  r2 - aborted context pc
++	@  r3 - aborted context cpsr
++	@
++	@ The abort handler must return the aborted address in r0, and
++	@ the fault status register in r1.  r9 must be preserved.
++	@
++#ifdef MULTI_DABORT
++	ldr	r4, .LCprocfns
++	mov	lr, pc
++	ldr	pc, [r4, #PROCESSOR_DABT_FUNC]
++#else
++	bl	CPU_DABORT_HANDLER
++#endif
++
++	@
++	@ set desired IRQ state, then call main handler
++	@
++	msr	cpsr_c, r9
++	mov	r2, sp
++	bl	do_DataAbort
++
++	@
++	@ IRQs off again before pulling preserved data off the stack
++	@
++	disable_irq_notrace
++
++	@
++	@ restore SPSR and restart the instruction
++	@
++	ldr	r2, [sp, #S_PSR]
++	svc_exit r2				@ return from exception
++ UNWIND(.fnend		)
++ENDPROC(__dabt_svc)
++
++	.align	5
++__irq_svc:
++	svc_entry
++
++#ifdef CONFIG_TRACE_IRQFLAGS
++	bl	trace_hardirqs_off
++#endif
++#ifdef CONFIG_PREEMPT
++	get_thread_info tsk
++	ldr	r8, [tsk, #TI_PREEMPT]		@ get preempt count
++	add	r7, r8, #1			@ increment it
++	str	r7, [tsk, #TI_PREEMPT]
++#endif
++
++	irq_handler
++#ifdef CONFIG_PREEMPT
++	str	r8, [tsk, #TI_PREEMPT]		@ restore preempt count
++	ldr	r0, [tsk, #TI_FLAGS]		@ get flags
++	teq	r8, #0				@ if preempt count != 0
++	movne	r0, #0				@ force flags to 0
++	tst	r0, #_TIF_NEED_RESCHED
++	blne	svc_preempt
++#endif
++	ldr	r4, [sp, #S_PSR]		@ irqs are already disabled
++#ifdef CONFIG_TRACE_IRQFLAGS
++	tst	r4, #PSR_I_BIT
++	bleq	trace_hardirqs_on
++#endif
++	svc_exit r4				@ return from exception
++ UNWIND(.fnend		)
++ENDPROC(__irq_svc)
++
++	.ltorg
++
++#ifdef CONFIG_PREEMPT
++svc_preempt:
++	mov	r8, lr
++1:	bl	preempt_schedule_irq		@ irq en/disable is done inside
++	ldr	r0, [tsk, #TI_FLAGS]		@ get new tasks TI_FLAGS
++	tst	r0, #_TIF_NEED_RESCHED
++	moveq	pc, r8				@ go again
++	b	1b
++#endif
++
++	.align	5
++__und_svc:
++#ifdef CONFIG_KPROBES
++	@ If a kprobe is about to simulate a "stmdb sp..." instruction,
++	@ it obviously needs free stack space which then will belong to
++	@ the saved context.
++	svc_entry 64
++#else
++	svc_entry
++#endif
++
++	@
++	@ call emulation code, which returns using r9 if it has emulated
++	@ the instruction, or the more conventional lr if we are to treat
++	@ this as a real undefined instruction
++	@
++	@  r0 - instruction
++	@
++#ifndef	CONFIG_THUMB2_KERNEL
++	ldr	r0, [r2, #-4]
++#else
++	ldrh	r0, [r2, #-2]			@ Thumb instruction at LR - 2
++	and	r9, r0, #0xf800
++	cmp	r9, #0xe800			@ 32-bit instruction if xx >= 0
++	ldrhhs	r9, [r2]			@ bottom 16 bits
++	orrhs	r0, r9, r0, lsl #16
++#endif
++	adr	r9, BSYM(1f)
++	bl	call_fpe
++
++	mov	r0, sp				@ struct pt_regs *regs
++	bl	do_undefinstr
++
++	@
++	@ IRQs off again before pulling preserved data off the stack
++	@
++1:	disable_irq_notrace
++
++	@
++	@ restore SPSR and restart the instruction
++	@
++	ldr	r2, [sp, #S_PSR]		@ Get SVC cpsr
++	svc_exit r2				@ return from exception
++ UNWIND(.fnend		)
++ENDPROC(__und_svc)
++
++	.align	5
++__pabt_svc:
++	svc_entry
++
++	@
++	@ re-enable interrupts if appropriate
++	@
++	mrs	r9, cpsr
++	tst	r3, #PSR_I_BIT
++	biceq	r9, r9, #PSR_I_BIT
++
++	mov	r0, r2			@ pass address of aborted instruction.
++#ifdef MULTI_PABORT
++	ldr	r4, .LCprocfns
++	mov	lr, pc
++	ldr	pc, [r4, #PROCESSOR_PABT_FUNC]
++#else
++	bl	CPU_PABORT_HANDLER
++#endif
++	msr	cpsr_c, r9			@ Maybe enable interrupts
++	mov	r2, sp				@ regs
++	bl	do_PrefetchAbort		@ call abort handler
++
++	@
++	@ IRQs off again before pulling preserved data off the stack
++	@
++	disable_irq_notrace
++
++	@
++	@ restore SPSR and restart the instruction
++	@
++	ldr	r2, [sp, #S_PSR]
++	svc_exit r2				@ return from exception
++ UNWIND(.fnend		)
++ENDPROC(__pabt_svc)
++
++	.align	5
++.LCcralign:
++	.word	cr_alignment
++#ifdef MULTI_DABORT
++.LCprocfns:
++	.word	processor
++#endif
++.LCfp:
++	.word	fp_enter
++
++/*
++ * User mode handlers
++ *
++ * EABI note: sp_svc is always 64-bit aligned here, so should S_FRAME_SIZE
++ */
++
++#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) && (S_FRAME_SIZE & 7)
++#error "sizeof(struct pt_regs) must be a multiple of 8"
++#endif
++
++	.macro	usr_entry
++ UNWIND(.fnstart	)
++ UNWIND(.cantunwind	)	@ don't unwind the user space
++	sub	sp, sp, #S_FRAME_SIZE
++ ARM(	stmib	sp, {r1 - r12}	)
++ THUMB(	stmia	sp, {r0 - r12}	)
++
++	ldmia	r0, {r1 - r3}
++	add	r0, sp, #S_PC		@ here for interlock avoidance
++	mov	r4, #-1			@  ""  ""     ""        ""
++
++	str	r1, [sp]		@ save the "real" r0 copied
++					@ from the exception stack
++
++	@
++	@ We are now ready to fill in the remaining blanks on the stack:
++	@
++	@  r2 - lr_<exception>, already fixed up for correct return/restart
++	@  r3 - spsr_<exception>
++	@  r4 - orig_r0 (see pt_regs definition in ptrace.h)
++	@
++	@ Also, separately save sp_usr and lr_usr
++	@
++	stmia	r0, {r2 - r4}
++ ARM(	stmdb	r0, {sp, lr}^			)
++ THUMB(	store_user_sp_lr r0, r1, S_SP - S_PC	)
++
++	@
++	@ Enable the alignment trap while in kernel mode
++	@
++	alignment_trap r0
++
++	@
++	@ Clear FP to mark the first stack frame
++	@
++	zero_fp
++	.endm
++
++	.macro	kuser_cmpxchg_check
++#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
++#ifndef CONFIG_MMU
++#warning "NPTL on non MMU needs fixing"
++#else
++	@ Make sure our user space atomic helper is restarted
++	@ if it was interrupted in a critical region.  Here we
++	@ perform a quick test inline since it should be false
++	@ 99.9999% of the time.  The rest is done out of line.
++	cmp	r2, #TASK_SIZE
++	blhs	kuser_cmpxchg_fixup
++#endif
++#endif
++	.endm
++
++	.align	5
++__dabt_usr:
++	usr_entry
++	kuser_cmpxchg_check
++
++	@
++	@ Call the processor-specific abort handler:
++	@
++	@  r2 - aborted context pc
++	@  r3 - aborted context cpsr
++	@
++	@ The abort handler must return the aborted address in r0, and
++	@ the fault status register in r1.
++	@
++#ifdef MULTI_DABORT
++	ldr	r4, .LCprocfns
++	mov	lr, pc
++	ldr	pc, [r4, #PROCESSOR_DABT_FUNC]
++#else
++	bl	CPU_DABORT_HANDLER
++#endif
++
++	@
++	@ IRQs on, then call the main handler
++	@
++	enable_irq
++	mov	r2, sp
++	adr	lr, BSYM(ret_from_exception)
++	b	do_DataAbort
++ UNWIND(.fnend		)
++ENDPROC(__dabt_usr)
++
++	.align	5
++__irq_usr:
++	usr_entry
++	kuser_cmpxchg_check
++
++	get_thread_info tsk
++#ifdef CONFIG_PREEMPT
++	ldr	r8, [tsk, #TI_PREEMPT]		@ get preempt count
++	add	r7, r8, #1			@ increment it
++	str	r7, [tsk, #TI_PREEMPT]
++#endif
++
++	irq_handler
++#ifdef CONFIG_PREEMPT
++	ldr	r0, [tsk, #TI_PREEMPT]
++	str	r8, [tsk, #TI_PREEMPT]
++	teq	r0, r7
++ ARM(	strne	r0, [r0, -r0]	)
++ THUMB(	movne	r0, #0		)
++ THUMB(	strne	r0, [r0]	)
++#endif
++
++	mov	why, #0
++	b	ret_to_user
++ UNWIND(.fnend		)
++ENDPROC(__irq_usr)
++
++	.ltorg
++
++	.align	5
++__und_usr:
++	usr_entry
++
++	@
++	@ fall through to the emulation code, which returns using r9 if
++	@ it has emulated the instruction, or the more conventional lr
++	@ if we are to treat this as a real undefined instruction
++	@
++	@  r0 - instruction
++	@
++	adr	r9, BSYM(ret_from_exception)
++	adr	lr, BSYM(__und_usr_unknown)
++	tst	r3, #PSR_T_BIT			@ Thumb mode?
++	itet	eq				@ explicit IT needed for the 1f label
++	subeq	r4, r2, #4			@ ARM instr at LR - 4
++	subne	r4, r2, #2			@ Thumb instr at LR - 2
++1:	ldreqt	r0, [r4]
++#ifdef CONFIG_CPU_ENDIAN_BE8
++	reveq	r0, r0				@ little endian instruction
++#endif
++	beq	call_fpe
++	@ Thumb instruction
++#if __LINUX_ARM_ARCH__ >= 7
++2:
++ ARM(	ldrht	r5, [r4], #2	)
++ THUMB(	ldrht	r5, [r4]	)
++ THUMB(	add	r4, r4, #2	)
++	and	r0, r5, #0xf800			@ mask bits 111x x... .... ....
++	cmp	r0, #0xe800			@ 32bit instruction if xx != 0
++	blo	__und_usr_unknown
++3:	ldrht	r0, [r4]
++	add	r2, r2, #2			@ r2 is PC + 2, make it PC + 4
++	orr	r0, r0, r5, lsl #16
++#else
++	b	__und_usr_unknown
++#endif
++ UNWIND(.fnend		)
++ENDPROC(__und_usr)
++
++	@
++	@ fallthrough to call_fpe
++	@
++
++/*
++ * The out of line fixup for the ldrt above.
++ */
++	.pushsection .fixup, "ax"
++4:	mov	pc, r9
++	.popsection
++	.pushsection __ex_table,"a"
++	.long	1b, 4b
++#if __LINUX_ARM_ARCH__ >= 7
++	.long	2b, 4b
++	.long	3b, 4b
++#endif
++	.popsection
++
++/*
++ * Check whether the instruction is a co-processor instruction.
++ * If yes, we need to call the relevant co-processor handler.
++ *
++ * Note that we don't do a full check here for the co-processor
++ * instructions; all instructions with bit 27 set are well
++ * defined.  The only instructions that should fault are the
++ * co-processor instructions.  However, we have to watch out
++ * for the ARM6/ARM7 SWI bug.
++ *
++ * NEON is a special case that has to be handled here. Not all
++ * NEON instructions are co-processor instructions, so we have
++ * to make a special case of checking for them. Plus, there's
++ * five groups of them, so we have a table of mask/opcode pairs
++ * to check against, and if any match then we branch off into the
++ * NEON handler code.
++ *
++ * Emulators may wish to make use of the following registers:
++ *  r0  = instruction opcode.
++ *  r2  = PC+4
++ *  r9  = normal "successful" return address
++ *  r10 = this threads thread_info structure.
++ *  lr  = unrecognised instruction return address
++ */
++	@
++	@ Fall-through from Thumb-2 __und_usr
++	@
++#ifdef CONFIG_NEON
++	adr	r6, .LCneon_thumb_opcodes
++	b	2f
++#endif
++call_fpe:
++#ifdef CONFIG_NEON
++	adr	r6, .LCneon_arm_opcodes
++2:
++	ldr	r7, [r6], #4			@ mask value
++	cmp	r7, #0				@ end mask?
++	beq	1f
++	and	r8, r0, r7
++	ldr	r7, [r6], #4			@ opcode bits matching in mask
++	cmp	r8, r7				@ NEON instruction?
++	bne	2b
++	get_thread_info r10
++	mov	r7, #1
++	strb	r7, [r10, #TI_USED_CP + 10]	@ mark CP#10 as used
++	strb	r7, [r10, #TI_USED_CP + 11]	@ mark CP#11 as used
++	b	do_vfp				@ let VFP handler handle this
++1:
++#endif
++	tst	r0, #0x08000000			@ only CDP/CPRT/LDC/STC have bit 27
++	tstne	r0, #0x04000000			@ bit 26 set on both ARM and Thumb-2
++#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
++	and	r8, r0, #0x0f000000		@ mask out op-code bits
++	teqne	r8, #0x0f000000			@ SWI (ARM6/7 bug)?
++#endif
++	moveq	pc, lr
++	get_thread_info r10			@ get current thread
++	and	r8, r0, #0x00000f00		@ mask out CP number
++ THUMB(	lsr	r8, r8, #8		)
++	mov	r7, #1
++	add	r6, r10, #TI_USED_CP
++ ARM(	strb	r7, [r6, r8, lsr #8]	)	@ set appropriate used_cp[]
++ THUMB(	strb	r7, [r6, r8]		)	@ set appropriate used_cp[]
++#ifdef CONFIG_IWMMXT
++	@ Test if we need to give access to iWMMXt coprocessors
++	ldr	r5, [r10, #TI_FLAGS]
++	rsbs	r7, r8, #(1 << 8)		@ CP 0 or 1 only
++	movcss	r7, r5, lsr #(TIF_USING_IWMMXT + 1)
++	bcs	iwmmxt_task_enable
++#endif
++ ARM(	add	pc, pc, r8, lsr #6	)
++ THUMB(	lsl	r8, r8, #2		)
++ THUMB(	add	pc, r8			)
++	nop
++
++	movw_pc	lr				@ CP#0
++	W(b)	do_fpe				@ CP#1 (FPE)
++	W(b)	do_fpe				@ CP#2 (FPE)
++	movw_pc	lr				@ CP#3
++#ifdef CONFIG_CRUNCH
++	b	crunch_task_enable		@ CP#4 (MaverickCrunch)
++	b	crunch_task_enable		@ CP#5 (MaverickCrunch)
++	b	crunch_task_enable		@ CP#6 (MaverickCrunch)
++#else
++	movw_pc	lr				@ CP#4
++	movw_pc	lr				@ CP#5
++	movw_pc	lr				@ CP#6
++#endif
++	movw_pc	lr				@ CP#7
++	movw_pc	lr				@ CP#8
++	movw_pc	lr				@ CP#9
++#ifdef CONFIG_VFP
++	W(b)	do_vfp				@ CP#10 (VFP)
++	W(b)	do_vfp				@ CP#11 (VFP)
++#else
++	movw_pc	lr				@ CP#10 (VFP)
++	movw_pc	lr				@ CP#11 (VFP)
++#endif
++	movw_pc	lr				@ CP#12
++	movw_pc	lr				@ CP#13
++	movw_pc	lr				@ CP#14 (Debug)
++	movw_pc	lr				@ CP#15 (Control)
++
++#ifdef CONFIG_NEON
++	.align	6
++
++.LCneon_arm_opcodes:
++	.word	0xfe000000			@ mask
++	.word	0xf2000000			@ opcode
++
++	.word	0xff100000			@ mask
++	.word	0xf4000000			@ opcode
++
++	.word	0x00000000			@ mask
++	.word	0x00000000			@ opcode
++
++.LCneon_thumb_opcodes:
++	.word	0xef000000			@ mask
++	.word	0xef000000			@ opcode
++
++	.word	0xff100000			@ mask
++	.word	0xf9000000			@ opcode
++
++	.word	0x00000000			@ mask
++	.word	0x00000000			@ opcode
++#endif
++
++do_fpe:
++	enable_irq
++	ldr	r4, .LCfp
++	add	r10, r10, #TI_FPSTATE		@ r10 = workspace
++	ldr	pc, [r4]			@ Call FP module USR entry point
++
++/*
++ * The FP module is called with these registers set:
++ *  r0  = instruction
++ *  r2  = PC+4
++ *  r9  = normal "successful" return address
++ *  r10 = FP workspace
++ *  lr  = unrecognised FP instruction return address
++ */
++
++	.pushsection .data
++ENTRY(fp_enter)
++	.word	no_fp
++	.popsection
++
++ENTRY(no_fp)
++	mov	pc, lr
++ENDPROC(no_fp)
++
++__und_usr_unknown:
++	enable_irq
++	mov	r0, sp
++	adr	lr, BSYM(ret_from_exception)
++	b	do_undefinstr
++ENDPROC(__und_usr_unknown)
++
++	.align	5
++__pabt_usr:
++	usr_entry
++
++	mov	r0, r2			@ pass address of aborted instruction.
++#ifdef MULTI_PABORT
++	ldr	r4, .LCprocfns
++	mov	lr, pc
++	ldr	pc, [r4, #PROCESSOR_PABT_FUNC]
++#else
++	bl	CPU_PABORT_HANDLER
++#endif
++	enable_irq				@ Enable interrupts
++	mov	r2, sp				@ regs
++	bl	do_PrefetchAbort		@ call abort handler
++ UNWIND(.fnend		)
++	/* fall through */
++/*
++ * This is the return code to user mode for abort handlers
++ */
++ENTRY(ret_from_exception)
++ UNWIND(.fnstart	)
++ UNWIND(.cantunwind	)
++	get_thread_info tsk
++	mov	why, #0
++	b	ret_to_user
++ UNWIND(.fnend		)
++ENDPROC(__pabt_usr)
++ENDPROC(ret_from_exception)
++
++/*
++ * Register switch for ARMv3 and ARMv4 processors
++ * r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info
++ * previous and next are guaranteed not to be the same.
++ */
++ENTRY(__switch_to)
++ UNWIND(.fnstart	)
++ UNWIND(.cantunwind	)
++	add	ip, r1, #TI_CPU_SAVE
++	ldr	r3, [r2, #TI_TP_VALUE]
++ ARM(	stmia	ip!, {r4 - sl, fp, sp, lr} )	@ Store most regs on stack
++ THUMB(	stmia	ip!, {r4 - sl, fp}	   )	@ Store most regs on stack
++ THUMB(	str	sp, [ip], #4		   )
++ THUMB(	str	lr, [ip], #4		   )
++#ifdef CONFIG_MMU
++	ldr	r6, [r2, #TI_CPU_DOMAIN]
++#endif
++#if defined(CONFIG_HAS_TLS_REG)
++	mcr	p15, 0, r3, c13, c0, 3		@ set TLS register
++#elif !defined(CONFIG_TLS_REG_EMUL)
++	mov	r4, #0xffff0fff
++	str	r3, [r4, #-15]			@ TLS val at 0xffff0ff0
++#endif
++#ifdef CONFIG_MMU
++	mcr	p15, 0, r6, c3, c0, 0		@ Set domain register
++#endif
++	mov	r5, r0
++	add	r4, r2, #TI_CPU_SAVE
++	ldr	r0, =thread_notify_head
++	mov	r1, #THREAD_NOTIFY_SWITCH
++	bl	atomic_notifier_call_chain
++ THUMB(	mov	ip, r4			   )
++	mov	r0, r5
++ ARM(	ldmia	r4, {r4 - sl, fp, sp, pc}  )	@ Load all regs saved previously
++ THUMB(	ldmia	ip!, {r4 - sl, fp}	   )	@ Load all regs saved previously
++ THUMB(	ldr	sp, [ip], #4		   )
++ THUMB(	ldr	pc, [ip]		   )
++ UNWIND(.fnend		)
++ENDPROC(__switch_to)
++
++	__INIT
++
++/*
++ * User helpers.
++ *
++ * These are segment of kernel provided user code reachable from user space
++ * at a fixed address in kernel memory.  This is used to provide user space
++ * with some operations which require kernel help because of unimplemented
++ * native feature and/or instructions in many ARM CPUs. The idea is for
++ * this code to be executed directly in user mode for best efficiency but
++ * which is too intimate with the kernel counter part to be left to user
++ * libraries.  In fact this code might even differ from one CPU to another
++ * depending on the available  instruction set and restrictions like on
++ * SMP systems.  In other words, the kernel reserves the right to change
++ * this code as needed without warning. Only the entry points and their
++ * results are guaranteed to be stable.
++ *
++ * Each segment is 32-byte aligned and will be moved to the top of the high
++ * vector page.  New segments (if ever needed) must be added in front of
++ * existing ones.  This mechanism should be used only for things that are
++ * really small and justified, and not be abused freely.
++ *
++ * User space is expected to implement those things inline when optimizing
++ * for a processor that has the necessary native support, but only if such
++ * resulting binaries are already to be incompatible with earlier ARM
++ * processors due to the use of unsupported instructions other than what
++ * is provided here.  In other words don't make binaries unable to run on
++ * earlier processors just for the sake of not using these kernel helpers
++ * if your compiled code is not going to use the new instructions for other
++ * purpose.
++ */
++ THUMB(	.arm	)
++
++	.macro	usr_ret, reg
++#ifdef CONFIG_ARM_THUMB
++	bx	\reg
++#else
++	mov	pc, \reg
++#endif
++	.endm
++
++	.align	5
++	.globl	__kuser_helper_start
++__kuser_helper_start:
++
++/*
++ * Reference prototype:
++ *
++ *	void __kernel_memory_barrier(void)
++ *
++ * Input:
++ *
++ *	lr = return address
++ *
++ * Output:
++ *
++ *	none
++ *
++ * Clobbered:
++ *
++ *	none
++ *
++ * Definition and user space usage example:
++ *
++ *	typedef void (__kernel_dmb_t)(void);
++ *	#define __kernel_dmb (*(__kernel_dmb_t *)0xffff0fa0)
++ *
++ * Apply any needed memory barrier to preserve consistency with data modified
++ * manually and __kuser_cmpxchg usage.
++ *
++ * This could be used as follows:
++ *
++ * #define __kernel_dmb() \
++ *         asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \
++ *	        : : : "r0", "lr","cc" )
++ */
++
++__kuser_memory_barrier:				@ 0xffff0fa0
++	smp_dmb
++	usr_ret	lr
++
++	.align	5
++
++/*
++ * Reference prototype:
++ *
++ *	int __kernel_cmpxchg(int oldval, int newval, int *ptr)
++ *
++ * Input:
++ *
++ *	r0 = oldval
++ *	r1 = newval
++ *	r2 = ptr
++ *	lr = return address
++ *
++ * Output:
++ *
++ *	r0 = returned value (zero or non-zero)
++ *	C flag = set if r0 == 0, clear if r0 != 0
++ *
++ * Clobbered:
++ *
++ *	r3, ip, flags
++ *
++ * Definition and user space usage example:
++ *
++ *	typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
++ *	#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
++ *
++ * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
++ * Return zero if *ptr was changed or non-zero if no exchange happened.
++ * The C flag is also set if *ptr was changed to allow for assembly
++ * optimization in the calling code.
++ *
++ * Notes:
++ *
++ *    - This routine already includes memory barriers as needed.
++ *
++ * For example, a user space atomic_add implementation could look like this:
++ *
++ * #define atomic_add(ptr, val) \
++ *	({ register unsigned int *__ptr asm("r2") = (ptr); \
++ *	   register unsigned int __result asm("r1"); \
++ *	   asm volatile ( \
++ *	       "1: @ atomic_add\n\t" \
++ *	       "ldr	r0, [r2]\n\t" \
++ *	       "mov	r3, #0xffff0fff\n\t" \
++ *	       "add	lr, pc, #4\n\t" \
++ *	       "add	r1, r0, %2\n\t" \
++ *	       "add	pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \
++ *	       "bcc	1b" \
++ *	       : "=&r" (__result) \
++ *	       : "r" (__ptr), "rIL" (val) \
++ *	       : "r0","r3","ip","lr","cc","memory" ); \
++ *	   __result; })
++ */
++
++__kuser_cmpxchg:				@ 0xffff0fc0
++
++#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
++
++	/*
++	 * Poor you.  No fast solution possible...
++	 * The kernel itself must perform the operation.
++	 * A special ghost syscall is used for that (see traps.c).
++	 */
++	stmfd	sp!, {r7, lr}
++	ldr	r7, =1f			@ it's 20 bits
++	swi	__ARM_NR_cmpxchg
++	ldmfd	sp!, {r7, pc}
++1:	.word	__ARM_NR_cmpxchg
++
++#elif __LINUX_ARM_ARCH__ < 6
++
++#ifdef CONFIG_MMU
++
++	/*
++	 * The only thing that can break atomicity in this cmpxchg
++	 * implementation is either an IRQ or a data abort exception
++	 * causing another process/thread to be scheduled in the middle
++	 * of the critical sequence.  To prevent this, code is added to
++	 * the IRQ and data abort exception handlers to set the pc back
++	 * to the beginning of the critical section if it is found to be
++	 * within that critical section (see kuser_cmpxchg_fixup).
++	 */
++1:	ldr	r3, [r2]			@ load current val
++	subs	r3, r3, r0			@ compare with oldval
++2:	streq	r1, [r2]			@ store newval if eq
++	rsbs	r0, r3, #0			@ set return val and C flag
++	usr_ret	lr
++
++	.text
++kuser_cmpxchg_fixup:
++	@ Called from kuser_cmpxchg_check macro.
++	@ r2 = address of interrupted insn (must be preserved).
++	@ sp = saved regs. r7 and r8 are clobbered.
++	@ 1b = first critical insn, 2b = last critical insn.
++	@ If r2 >= 1b and r2 <= 2b then saved pc_usr is set to 1b.
++	mov	r7, #0xffff0fff
++	sub	r7, r7, #(0xffff0fff - (0xffff0fc0 + (1b - __kuser_cmpxchg)))
++	subs	r8, r2, r7
++	rsbcss	r8, r8, #(2b - 1b)
++	strcs	r7, [sp, #S_PC]
++	mov	pc, lr
++	.previous
++
++#else
++#warning "NPTL on non MMU needs fixing"
++	mov	r0, #-1
++	adds	r0, r0, #0
++	usr_ret	lr
++#endif
++
++#else
++
++	smp_dmb
++1:	ldrex	r3, [r2]
++	subs	r3, r3, r0
++	strexeq	r3, r1, [r2]
++	teqeq	r3, #1
++	beq	1b
++	rsbs	r0, r3, #0
++	/* beware -- each __kuser slot must be 8 instructions max */
++#ifdef CONFIG_SMP
++	b	__kuser_memory_barrier
++#else
++	usr_ret	lr
++#endif
++
++#endif
++
++	.align	5
++
++/*
++ * Reference prototype:
++ *
++ *	int __kernel_get_tls(void)
++ *
++ * Input:
++ *
++ *	lr = return address
++ *
++ * Output:
++ *
++ *	r0 = TLS value
++ *
++ * Clobbered:
++ *
++ *	none
++ *
++ * Definition and user space usage example:
++ *
++ *	typedef int (__kernel_get_tls_t)(void);
++ *	#define __kernel_get_tls (*(__kernel_get_tls_t *)0xffff0fe0)
++ *
++ * Get the TLS value as previously set via the __ARM_NR_set_tls syscall.
++ *
++ * This could be used as follows:
++ *
++ * #define __kernel_get_tls() \
++ *	({ register unsigned int __val asm("r0"); \
++ *         asm( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #31" \
++ *	        : "=r" (__val) : : "lr","cc" ); \
++ *	   __val; })
++ */
++
++__kuser_get_tls:				@ 0xffff0fe0
++
++#if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL)
++	ldr	r0, [pc, #(16 - 8)]		@ TLS stored at 0xffff0ff0
++#else
++	mrc	p15, 0, r0, c13, c0, 3		@ read TLS register
++#endif
++	usr_ret	lr
++
++	.rep	5
++	.word	0			@ pad up to __kuser_helper_version
++	.endr
++
++/*
++ * Reference declaration:
++ *
++ *	extern unsigned int __kernel_helper_version;
++ *
++ * Definition and user space usage example:
++ *
++ *	#define __kernel_helper_version (*(unsigned int *)0xffff0ffc)
++ *
++ * User space may read this to determine the curent number of helpers
++ * available.
++ */
++
++__kuser_helper_version:				@ 0xffff0ffc
++	.word	((__kuser_helper_end - __kuser_helper_start) >> 5)
++
++	.globl	__kuser_helper_end
++__kuser_helper_end:
++
++ THUMB(	.thumb	)
++
++/*
++ * Vector stubs.
++ *
++ * This code is copied to 0xffff0200 so we can use branches in the
++ * vectors, rather than ldr's.  Note that this code must not
++ * exceed 0x300 bytes.
++ *
++ * Common stub entry macro:
++ *   Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
++ *
++ * SP points to a minimal amount of processor-private memory, the address
++ * of which is copied into r0 for the mode specific abort handler.
++ */
++	.macro	vector_stub, name, mode, correction=0
++	.align	5
++
++vector_\name:
++	.if \correction
++	sub	lr, lr, #\correction
++	.endif
++
++	@
++	@ Save r0, lr_<exception> (parent PC) and spsr_<exception>
++	@ (parent CPSR)
++	@
++	stmia	sp, {r0, lr}		@ save r0, lr
++	mrs	lr, spsr
++	str	lr, [sp, #8]		@ save spsr
++
++	@
++	@ Prepare for SVC32 mode.  IRQs remain disabled.
++	@
++	mrs	r0, cpsr
++	eor	r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE)
++	msr	spsr_cxsf, r0
++
++	@
++	@ the branch table must immediately follow this code
++	@
++	and	lr, lr, #0x0f
++ THUMB(	adr	r0, 1f			)
++ THUMB(	ldr	lr, [r0, lr, lsl #2]	)
++	mov	r0, sp
++ ARM(	ldr	lr, [pc, lr, lsl #2]	)
++	movs	pc, lr			@ branch to handler in SVC mode
++ENDPROC(vector_\name)
++
++	.align	2
++	@ handler addresses follow this label
++1:
++	.endm
++
++	.globl	__stubs_start
++__stubs_start:
++/*
++ * Interrupt dispatcher
++ */
++	vector_stub	irq, IRQ_MODE, 4
++
++	.long	__irq_usr			@  0  (USR_26 / USR_32)
++	.long	__irq_invalid			@  1  (FIQ_26 / FIQ_32)
++	.long	__irq_invalid			@  2  (IRQ_26 / IRQ_32)
++	.long	__irq_svc			@  3  (SVC_26 / SVC_32)
++	.long	__irq_invalid			@  4
++	.long	__irq_invalid			@  5
++	.long	__irq_invalid			@  6
++	.long	__irq_invalid			@  7
++	.long	__irq_invalid			@  8
++	.long	__irq_invalid			@  9
++	.long	__irq_invalid			@  a
++	.long	__irq_invalid			@  b
++	.long	__irq_invalid			@  c
++	.long	__irq_invalid			@  d
++	.long	__irq_invalid			@  e
++	.long	__irq_invalid			@  f
++
++/*
++ * Data abort dispatcher
++ * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
++ */
++	vector_stub	dabt, ABT_MODE, 8
++
++	.long	__dabt_usr			@  0  (USR_26 / USR_32)
++	.long	__dabt_invalid			@  1  (FIQ_26 / FIQ_32)
++	.long	__dabt_invalid			@  2  (IRQ_26 / IRQ_32)
++	.long	__dabt_svc			@  3  (SVC_26 / SVC_32)
++	.long	__dabt_invalid			@  4
++	.long	__dabt_invalid			@  5
++	.long	__dabt_invalid			@  6
++	.long	__dabt_invalid			@  7
++	.long	__dabt_invalid			@  8
++	.long	__dabt_invalid			@  9
++	.long	__dabt_invalid			@  a
++	.long	__dabt_invalid			@  b
++	.long	__dabt_invalid			@  c
++	.long	__dabt_invalid			@  d
++	.long	__dabt_invalid			@  e
++	.long	__dabt_invalid			@  f
++
++/*
++ * Prefetch abort dispatcher
++ * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
++ */
++	vector_stub	pabt, ABT_MODE, 4
++
++	.long	__pabt_usr			@  0 (USR_26 / USR_32)
++	.long	__pabt_invalid			@  1 (FIQ_26 / FIQ_32)
++	.long	__pabt_invalid			@  2 (IRQ_26 / IRQ_32)
++	.long	__pabt_svc			@  3 (SVC_26 / SVC_32)
++	.long	__pabt_invalid			@  4
++	.long	__pabt_invalid			@  5
++	.long	__pabt_invalid			@  6
++	.long	__pabt_invalid			@  7
++	.long	__pabt_invalid			@  8
++	.long	__pabt_invalid			@  9
++	.long	__pabt_invalid			@  a
++	.long	__pabt_invalid			@  b
++	.long	__pabt_invalid			@  c
++	.long	__pabt_invalid			@  d
++	.long	__pabt_invalid			@  e
++	.long	__pabt_invalid			@  f
++
++/*
++ * Undef instr entry dispatcher
++ * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
++ */
++	vector_stub	und, UND_MODE
++
++	.long	__und_usr			@  0 (USR_26 / USR_32)
++	.long	__und_invalid			@  1 (FIQ_26 / FIQ_32)
++	.long	__und_invalid			@  2 (IRQ_26 / IRQ_32)
++	.long	__und_svc			@  3 (SVC_26 / SVC_32)
++	.long	__und_invalid			@  4
++	.long	__und_invalid			@  5
++	.long	__und_invalid			@  6
++	.long	__und_invalid			@  7
++	.long	__und_invalid			@  8
++	.long	__und_invalid			@  9
++	.long	__und_invalid			@  a
++	.long	__und_invalid			@  b
++	.long	__und_invalid			@  c
++	.long	__und_invalid			@  d
++	.long	__und_invalid			@  e
++	.long	__und_invalid			@  f
++
++	.align	5
++
++/*=============================================================================
++ * Undefined FIQs
++ *-----------------------------------------------------------------------------
++ * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
++ * MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg.
++ * Basically to switch modes, we *HAVE* to clobber one register...  brain
++ * damage alert!  I don't think that we can execute any code in here in any
++ * other mode than FIQ...  Ok you can switch to another mode, but you can't
++ * get out of that mode without clobbering one register.
++ */
++vector_fiq:
++	disable_fiq
++	subs	pc, lr, #4
++
++/*=============================================================================
++ * Address exception handler
++ *-----------------------------------------------------------------------------
++ * These aren't too critical.
++ * (they're not supposed to happen, and won't happen in 32-bit data mode).
++ */
++
++vector_addrexcptn:
++	b	vector_addrexcptn
++
++/*
++ * We group all the following data together to optimise
++ * for CPUs with separate I & D caches.
++ */
++	.align	5
++
++.LCvswi:
++	.word	vector_swi
++
++	.globl	__stubs_end
++__stubs_end:
++
++	.equ	stubs_offset, __vectors_start + 0x200 - __stubs_start
++
++	.globl	__vectors_start
++__vectors_start:
++ ARM(	swi	SYS_ERROR0	)
++ THUMB(	svc	#0		)
++ THUMB(	nop			)
++	W(b)	vector_und + stubs_offset
++	W(ldr)	pc, .LCvswi + stubs_offset
++	W(b)	vector_pabt + stubs_offset
++	W(b)	vector_dabt + stubs_offset
++	W(b)	vector_addrexcptn + stubs_offset
++	W(b)	vector_irq + stubs_offset
++	W(b)	vector_fiq + stubs_offset
++
++	.globl	__vectors_end
++__vectors_end:
++
++	.data
++
++	.globl	cr_alignment
++	.globl	cr_no_alignment
++cr_alignment:
++	.space	4
++cr_no_alignment:
++	.space	4
+diff -rupN linux-2.6.35.11/arch/arm/kernel/head-common.S linux-2.6.35.11-ts7500/arch/arm/kernel/head-common.S
+--- linux-2.6.35.11/arch/arm/kernel/head-common.S	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/head-common.S	2011-03-14 11:18:24.000000000 -0400
+@@ -39,6 +39,16 @@ __switch_data:
+  *  r9  = processor ID
+  */
+ __mmap_switched:
++
++# We come here right after the MMU is enabled
++
++#ifdef CONFIG_DEBUG_LL
++@   stmfd sp!, {r0, r1, r2, r3, r9, lr}
++@   adr	r0, str_mmap_switched
++@	bl	printascii
++@   ldmfd sp!, {r0, r1, r2, r3, r9, lr}
++#endif
++
+ 	adr	r3, __switch_data + 4
+ 
+ 	ldmia	r3!, {r4, r5, r6, r7}
+@@ -53,6 +63,7 @@ __mmap_switched:
+ 	strcc	fp, [r6],#4
+ 	bcc	1b
+ 
++   
+  ARM(	ldmia	r3, {r4, r5, r6, r7, sp})
+  THUMB(	ldmia	r3, {r4, r5, r6, r7}	)
+  THUMB(	ldr	sp, [r3, #16]		)
+@@ -61,7 +72,23 @@ __mmap_switched:
+ 	str	r2, [r6]			@ Save atags pointer
+ 	bic	r4, r0, #CR_A			@ Clear 'A' bit
+ 	stmia	r7, {r0, r4}			@ Save control register values
++   
++#ifdef CONFIG_DEBUG_LL
++   stmfd sp!, {r0, r1, r2, r3, r9, lr}
++   adr	r0, str_mmap_switched_done
++	bl	printascii
++   ldmfd sp!, {r0, r1, r2, r3, r9, lr}
++#endif
++
++
+ 	b	start_kernel
++
++#ifdef CONFIG_DEBUG_LL
++str_mmap_switched: .asciz "str_mmap_switched\n"   
++str_mmap_switched_done: .asciz "str_mmap_switched_done\n"
++.align 4
++#endif   
++   
+ ENDPROC(__mmap_switched)
+ 
+ /*
+@@ -74,7 +101,7 @@ ENDPROC(__mmap_switched)
+  * machine ID for example).
+  */
+ __error_p:
+-#ifdef CONFIG_DEBUG_LL
++#ifdef CONFIG_DEBUG_LL   
+ 	adr	r0, str_p1
+ 	bl	printascii
+ 	mov	r0, r9
+diff -rupN linux-2.6.35.11/arch/arm/kernel/head.S linux-2.6.35.11-ts7500/arch/arm/kernel/head.S
+--- linux-2.6.35.11/arch/arm/kernel/head.S	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/head.S	2011-03-14 11:18:24.000000000 -0400
+@@ -22,6 +22,10 @@
+ #include <asm/thread_info.h>
+ #include <asm/system.h>
+ 
++#if defined(CONFIG_ARCH_STR9100) || defined(CONFIG_ARCH_STR8100)
++//#define PROCINFO_INITFUNC	12
++#endif
++
+ #if (PHYS_OFFSET & 0x001fffff)
+ #error "PHYS_OFFSET must be at an even 2MiB boundary!"
+ #endif
+@@ -78,16 +82,75 @@
+ ENTRY(stext)
+ 	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
+ 						@ and irqs disabled
++
++                       
++#ifdef CONFIG_DEBUG_LL
++   stmfd sp!, {r0, r1, r2}
++   mov r6, r1   
++   adr	r0, str_kernel_start
++	bl	printascii
++   adr   r0, str_machine_id
++   bl	printascii
++   mov r0, r6
++   bl printhex8
++   mov r0, #'\n'
++   bl printch
++   ldmfd sp!, {r0, r1, r2}
++#endif
++                  
+ 	mrc	p15, 0, r9, c0, c0		@ get processor id
++   
++#ifdef CONFIG_DEBUG_LL
++   stmfd sp!, {r0, r1, r2}  
++   adr	r0, str_processor_id
++	bl	printascii
++   mov r0, r9
++   bl printhex8
++   mov r0, #'\n'
++   bl printch
++   ldmfd sp!, {r0, r1, r2}
++#endif   
++   
+ 	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid
+ 	movs	r10, r5				@ invalid processor (r5=0)?
+ 	beq	__error_p			@ yes, error 'p'
+ 	bl	__lookup_machine_type		@ r5=machinfo
+ 	movs	r8, r5				@ invalid machine (r5=0)?
+-	beq	__error_a			@ yes, error 'a'
++	beq	__error_a			@ yes, error 'a'   
+ 	bl	__vet_atags
+ 	bl	__create_page_tables
+ 
++   
++###########################
++
++	mov	ip, #0	
++	mcr	p15, 0, ip, c7,c14, 2		@ clean/flush D-cache
++	mcr	p15, 0, ip, c7, c10, 4		@ drain write buffer
++	mcr	p15, 0, ip, c7, c5, 6		@ invalidate BTB
++	nop
++	nop
++   nop 
++   nop
++   
++#################################
++   
++#ifdef CONFIG_DEBUG_LL
++   stmfd sp!, {r0, r1, r2}  
++   adr	r0, str_procinfo_at
++	bl	printascii
++   mov r0, r10
++   bl printhex8
++   mov r0, #'\n'   
++   bl printch
++   adr	r0, str_initfunc_offset
++	bl	printascii
++   mov r0, #PROCINFO_INITFUNC
++   bl printhex8
++   mov r0, #'\n'   
++   bl printch
++   ldmfd sp!, {r0, r1, r2}
++#endif      
++   
+ 	/*
+ 	 * The following calls CPU specific code in a position independent
+ 	 * manner.  See arch/arm/mm/proc-*.S for details.  r10 = base of
+@@ -101,6 +164,15 @@ ENTRY(stext)
+  ARM(	add	pc, r10, #PROCINFO_INITFUNC	)
+  THUMB(	add	r12, r10, #PROCINFO_INITFUNC	)
+  THUMB(	mov	pc, r12				)
++
++#ifdef CONFIG_DEBUG_LL
++str_kernel_start: .asciz "kernel_start\n"   
++str_machine_id: .asciz "machine ID: 0x"
++str_processor_id: .asciz "processor ID: 0x"
++str_procinfo_at:  .asciz "procinfo at:  0x"
++str_initfunc_offset:  .asciz "PROCINFO_INITFUNC:  0x"
++.align 4
++#endif   
+ ENDPROC(stext)
+ 
+ #if defined(CONFIG_SMP)
+@@ -158,6 +230,13 @@ __secondary_data:
+  * registers.
+  */
+ __enable_mmu:
++#ifdef CONFIG_DEBUG_LL
++@   stmfd sp!, {r0, r1, r2, r3, r6, r13, lr}
++@   adr	r0, str_enable_mmu
++@	bl	printascii
++@   ldmfd sp!, {r0, r1, r2, r3, r6, r13, lr}
++#endif
++
+ #ifdef CONFIG_ALIGNMENT_TRAP
+ 	orr	r0, r0, #CR_A
+ #else
+@@ -179,6 +258,12 @@ __enable_mmu:
+ 	mcr	p15, 0, r5, c3, c0, 0		@ load domain access register
+ 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
+ 	b	__turn_mmu_on
++   
++#ifdef CONFIG_DEBUG_LL   
++str_enable_mmu: .asciz "__enable_mmu\n"
++str_enable_mmu_done: .asciz "__enable_mmu done\n"
++.align 4
++#endif
+ ENDPROC(__enable_mmu)
+ 
+ /*
+@@ -196,10 +281,19 @@ ENDPROC(__enable_mmu)
+ __turn_mmu_on:
+ 	mov	r0, r0
+ 	mcr	p15, 0, r0, c1, c0, 0		@ write control reg
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++	nop
++	nop
++	nop
++	nop
++#endif   
+ 	mrc	p15, 0, r3, c0, c0, 0		@ read id reg
++   
+ 	mov	r3, r3
+-	mov	r3, r13
++   mov	r3, r3
++	mov	r3, r13   
+ 	mov	pc, r3
++   
+ ENDPROC(__turn_mmu_on)
+ 
+ 
+@@ -217,6 +311,12 @@ ENDPROC(__turn_mmu_on)
+  *  r4 = physical page table address
+  */
+ __create_page_tables:
++#ifdef CONFIG_DEBUG_LL
++   mov r6, lr
++   adr	r0, str_create_page_tables
++	bl	printascii
++   mov lr, r6
++#endif
+ 	pgtbl	r4				@ page table address
+ 
+ 	/*
+@@ -281,14 +381,15 @@ __create_page_tables:
+ 	/*
+ 	 * Then map first 1MB of ram in case it contains our boot params.
+ 	 */
+-	add	r0, r4, #PAGE_OFFSET >> 18
++	add	r0, r4, #PAGE_OFFSET >> 18   
+ 	orr	r6, r7, #(PHYS_OFFSET & 0xff000000)
+ 	.if	(PHYS_OFFSET & 0x00f00000)
+ 	orr	r6, r6, #(PHYS_OFFSET & 0x00f00000)
+ 	.endif
+ 	str	r6, [r0]
+ 
+-#ifdef CONFIG_DEBUG_LL
++@#if defined(CONFIG_DEBUG_LL) || defined(CONFIG_ARCH_STR9100) || defined(CONFIG_ARCH_STR8100)
++#if defined(CONFIG_DEBUG_LL)
+ 	ldr	r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
+ 	/*
+ 	 * Map in IO space for serial debugging.
+@@ -329,7 +430,20 @@ __create_page_tables:
+ 	str	r3, [r0]
+ #endif
+ #endif
++
++#ifdef CONFIG_DEBUG_LL
++   mov r6, lr
++   adr	r0, str_create_page_tables_done
++	bl	printascii
++   mov lr, r6
++#endif
++
+ 	mov	pc, lr
++#ifdef CONFIG_DEBUG_LL
++str_create_page_tables: .asciz "create_page_tables\n"   
++str_create_page_tables_done: .asciz "create_page_tables_done\n"
++.align 4
++#endif
+ ENDPROC(__create_page_tables)
+ 	.ltorg
+ 
+diff -rupN linux-2.6.35.11/arch/arm/kernel/process.c linux-2.6.35.11-ts7500/arch/arm/kernel/process.c
+--- linux-2.6.35.11/arch/arm/kernel/process.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/process.c	2011-03-14 11:18:24.000000000 -0400
+@@ -126,9 +126,17 @@ EXPORT_SYMBOL_GPL(arm_pm_restart);
+  */
+ static void default_idle(void)
+ {
++#ifndef CONFIG_CPU_FA_IDLE
++                local_irq_disable();
++#endif
++
+ 	if (!need_resched())
+ 		arch_idle();
+-	local_irq_enable();
++//	local_irq_enable();
++#ifndef CONFIG_CPU_FA_IDLE
++        local_irq_enable();
++#endif
++
+ }
+ 
+ void (*pm_idle)(void) = default_idle;
+diff -rupN linux-2.6.35.11/arch/arm/kernel/process.c.orig linux-2.6.35.11-ts7500/arch/arm/kernel/process.c.orig
+--- linux-2.6.35.11/arch/arm/kernel/process.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/process.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,428 @@
++/*
++ *  linux/arch/arm/kernel/process.c
++ *
++ *  Copyright (C) 1996-2000 Russell King - Converted to ARM.
++ *  Original Copyright (C) 1995  Linus Torvalds
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <stdarg.h>
++
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/stddef.h>
++#include <linux/unistd.h>
++#include <linux/user.h>
++#include <linux/delay.h>
++#include <linux/reboot.h>
++#include <linux/interrupt.h>
++#include <linux/kallsyms.h>
++#include <linux/init.h>
++#include <linux/cpu.h>
++#include <linux/elfcore.h>
++#include <linux/pm.h>
++#include <linux/tick.h>
++#include <linux/utsname.h>
++#include <linux/uaccess.h>
++
++#include <asm/leds.h>
++#include <asm/processor.h>
++#include <asm/system.h>
++#include <asm/thread_notify.h>
++#include <asm/stacktrace.h>
++#include <asm/mach/time.h>
++
++static const char *processor_modes[] = {
++  "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
++  "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
++  "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" ,
++  "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
++};
++
++static const char *isa_modes[] = {
++  "ARM" , "Thumb" , "Jazelle", "ThumbEE"
++};
++
++extern void setup_mm_for_reboot(char mode);
++
++static volatile int hlt_counter;
++
++#include <mach/system.h>
++
++void disable_hlt(void)
++{
++	hlt_counter++;
++}
++
++EXPORT_SYMBOL(disable_hlt);
++
++void enable_hlt(void)
++{
++	hlt_counter--;
++}
++
++EXPORT_SYMBOL(enable_hlt);
++
++static int __init nohlt_setup(char *__unused)
++{
++	hlt_counter = 1;
++	return 1;
++}
++
++static int __init hlt_setup(char *__unused)
++{
++	hlt_counter = 0;
++	return 1;
++}
++
++__setup("nohlt", nohlt_setup);
++__setup("hlt", hlt_setup);
++
++void arm_machine_restart(char mode, const char *cmd)
++{
++	/*
++	 * Clean and disable cache, and turn off interrupts
++	 */
++	cpu_proc_fin();
++
++	/*
++	 * Tell the mm system that we are going to reboot -
++	 * we may need it to insert some 1:1 mappings so that
++	 * soft boot works.
++	 */
++	setup_mm_for_reboot(mode);
++
++	/*
++	 * Now call the architecture specific reboot code.
++	 */
++	arch_reset(mode, cmd);
++
++	/*
++	 * Whoops - the architecture was unable to reboot.
++	 * Tell the user!
++	 */
++	mdelay(1000);
++	printk("Reboot failed -- System halted\n");
++	while (1);
++}
++
++/*
++ * Function pointers to optional machine specific functions
++ */
++void (*pm_power_off)(void);
++EXPORT_SYMBOL(pm_power_off);
++
++void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart;
++EXPORT_SYMBOL_GPL(arm_pm_restart);
++
++
++/*
++ * This is our default idle handler.  We need to disable
++ * interrupts here to ensure we don't miss a wakeup call.
++ */
++static void default_idle(void)
++{
++	if (!need_resched())
++		arch_idle();
++	local_irq_enable();
++}
++
++void (*pm_idle)(void) = default_idle;
++EXPORT_SYMBOL(pm_idle);
++
++/*
++ * The idle thread, has rather strange semantics for calling pm_idle,
++ * but this is what x86 does and we need to do the same, so that
++ * things like cpuidle get called in the same way.  The only difference
++ * is that we always respect 'hlt_counter' to prevent low power idle.
++ */
++void cpu_idle(void)
++{
++	local_fiq_enable();
++
++	/* endless idle loop with no priority at all */
++	while (1) {
++		tick_nohz_stop_sched_tick(1);
++		leds_event(led_idle_start);
++		while (!need_resched()) {
++#ifdef CONFIG_HOTPLUG_CPU
++			if (cpu_is_offline(smp_processor_id()))
++				cpu_die();
++#endif
++
++			local_irq_disable();
++			if (hlt_counter) {
++				local_irq_enable();
++				cpu_relax();
++			} else {
++				stop_critical_timings();
++				pm_idle();
++				start_critical_timings();
++				/*
++				 * This will eventually be removed - pm_idle
++				 * functions should always return with IRQs
++				 * enabled.
++				 */
++				WARN_ON(irqs_disabled());
++				local_irq_enable();
++			}
++		}
++		leds_event(led_idle_end);
++		tick_nohz_restart_sched_tick();
++		preempt_enable_no_resched();
++		schedule();
++		preempt_disable();
++	}
++}
++
++static char reboot_mode = 'h';
++
++int __init reboot_setup(char *str)
++{
++	reboot_mode = str[0];
++	return 1;
++}
++
++__setup("reboot=", reboot_setup);
++
++void machine_halt(void)
++{
++}
++
++
++void machine_power_off(void)
++{
++	if (pm_power_off)
++		pm_power_off();
++}
++
++void machine_restart(char *cmd)
++{
++	arm_pm_restart(reboot_mode, cmd);
++}
++
++void __show_regs(struct pt_regs *regs)
++{
++	unsigned long flags;
++	char buf[64];
++
++	printk("CPU: %d    %s  (%s %.*s)\n",
++		raw_smp_processor_id(), print_tainted(),
++		init_utsname()->release,
++		(int)strcspn(init_utsname()->version, " "),
++		init_utsname()->version);
++	print_symbol("PC is at %s\n", instruction_pointer(regs));
++	print_symbol("LR is at %s\n", regs->ARM_lr);
++	printk("pc : [<%08lx>]    lr : [<%08lx>]    psr: %08lx\n"
++	       "sp : %08lx  ip : %08lx  fp : %08lx\n",
++		regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr,
++		regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
++	printk("r10: %08lx  r9 : %08lx  r8 : %08lx\n",
++		regs->ARM_r10, regs->ARM_r9,
++		regs->ARM_r8);
++	printk("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
++		regs->ARM_r7, regs->ARM_r6,
++		regs->ARM_r5, regs->ARM_r4);
++	printk("r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
++		regs->ARM_r3, regs->ARM_r2,
++		regs->ARM_r1, regs->ARM_r0);
++
++	flags = regs->ARM_cpsr;
++	buf[0] = flags & PSR_N_BIT ? 'N' : 'n';
++	buf[1] = flags & PSR_Z_BIT ? 'Z' : 'z';
++	buf[2] = flags & PSR_C_BIT ? 'C' : 'c';
++	buf[3] = flags & PSR_V_BIT ? 'V' : 'v';
++	buf[4] = '\0';
++
++	printk("Flags: %s  IRQs o%s  FIQs o%s  Mode %s  ISA %s  Segment %s\n",
++		buf, interrupts_enabled(regs) ? "n" : "ff",
++		fast_interrupts_enabled(regs) ? "n" : "ff",
++		processor_modes[processor_mode(regs)],
++		isa_modes[isa_mode(regs)],
++		get_fs() == get_ds() ? "kernel" : "user");
++#ifdef CONFIG_CPU_CP15
++	{
++		unsigned int ctrl;
++
++		buf[0] = '\0';
++#ifdef CONFIG_CPU_CP15_MMU
++		{
++			unsigned int transbase, dac;
++			asm("mrc p15, 0, %0, c2, c0\n\t"
++			    "mrc p15, 0, %1, c3, c0\n"
++			    : "=r" (transbase), "=r" (dac));
++			snprintf(buf, sizeof(buf), "  Table: %08x  DAC: %08x",
++			  	transbase, dac);
++		}
++#endif
++		asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl));
++
++		printk("Control: %08x%s\n", ctrl, buf);
++	}
++#endif
++}
++
++void show_regs(struct pt_regs * regs)
++{
++	printk("\n");
++	printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm);
++	__show_regs(regs);
++	__backtrace();
++}
++
++ATOMIC_NOTIFIER_HEAD(thread_notify_head);
++
++EXPORT_SYMBOL_GPL(thread_notify_head);
++
++/*
++ * Free current thread data structures etc..
++ */
++void exit_thread(void)
++{
++	thread_notify(THREAD_NOTIFY_EXIT, current_thread_info());
++}
++
++void flush_thread(void)
++{
++	struct thread_info *thread = current_thread_info();
++	struct task_struct *tsk = current;
++
++	memset(thread->used_cp, 0, sizeof(thread->used_cp));
++	memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
++	memset(&thread->fpstate, 0, sizeof(union fp_state));
++
++	thread_notify(THREAD_NOTIFY_FLUSH, thread);
++}
++
++void release_thread(struct task_struct *dead_task)
++{
++}
++
++asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
++
++int
++copy_thread(unsigned long clone_flags, unsigned long stack_start,
++	    unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs)
++{
++	struct thread_info *thread = task_thread_info(p);
++	struct pt_regs *childregs = task_pt_regs(p);
++
++	*childregs = *regs;
++	childregs->ARM_r0 = 0;
++	childregs->ARM_sp = stack_start;
++
++	memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
++	thread->cpu_context.sp = (unsigned long)childregs;
++	thread->cpu_context.pc = (unsigned long)ret_from_fork;
++
++	if (clone_flags & CLONE_SETTLS)
++		thread->tp_value = regs->ARM_r3;
++
++	return 0;
++}
++
++/*
++ * Fill in the task's elfregs structure for a core dump.
++ */
++int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs)
++{
++	elf_core_copy_regs(elfregs, task_pt_regs(t));
++	return 1;
++}
++
++/*
++ * fill in the fpe structure for a core dump...
++ */
++int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
++{
++	struct thread_info *thread = current_thread_info();
++	int used_math = thread->used_cp[1] | thread->used_cp[2];
++
++	if (used_math)
++		memcpy(fp, &thread->fpstate.soft, sizeof (*fp));
++
++	return used_math != 0;
++}
++EXPORT_SYMBOL(dump_fpu);
++
++/*
++ * Shuffle the argument into the correct register before calling the
++ * thread function.  r4 is the thread argument, r5 is the pointer to
++ * the thread function, and r6 points to the exit function.
++ */
++extern void kernel_thread_helper(void);
++asm(	".pushsection .text\n"
++"	.align\n"
++"	.type	kernel_thread_helper, #function\n"
++"kernel_thread_helper:\n"
++#ifdef CONFIG_TRACE_IRQFLAGS
++"	bl	trace_hardirqs_on\n"
++#endif
++"	msr	cpsr_c, r7\n"
++"	mov	r0, r4\n"
++"	mov	lr, r6\n"
++"	mov	pc, r5\n"
++"	.size	kernel_thread_helper, . - kernel_thread_helper\n"
++"	.popsection");
++
++#ifdef CONFIG_ARM_UNWIND
++extern void kernel_thread_exit(long code);
++asm(	".pushsection .text\n"
++"	.align\n"
++"	.type	kernel_thread_exit, #function\n"
++"kernel_thread_exit:\n"
++"	.fnstart\n"
++"	.cantunwind\n"
++"	bl	do_exit\n"
++"	nop\n"
++"	.fnend\n"
++"	.size	kernel_thread_exit, . - kernel_thread_exit\n"
++"	.popsection");
++#else
++#define kernel_thread_exit	do_exit
++#endif
++
++/*
++ * Create a kernel thread.
++ */
++pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
++{
++	struct pt_regs regs;
++
++	memset(&regs, 0, sizeof(regs));
++
++	regs.ARM_r4 = (unsigned long)arg;
++	regs.ARM_r5 = (unsigned long)fn;
++	regs.ARM_r6 = (unsigned long)kernel_thread_exit;
++	regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
++	regs.ARM_pc = (unsigned long)kernel_thread_helper;
++	regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;
++
++	return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
++}
++EXPORT_SYMBOL(kernel_thread);
++
++unsigned long get_wchan(struct task_struct *p)
++{
++	struct stackframe frame;
++	int count = 0;
++	if (!p || p == current || p->state == TASK_RUNNING)
++		return 0;
++
++	frame.fp = thread_saved_fp(p);
++	frame.sp = thread_saved_sp(p);
++	frame.lr = 0;			/* recovered from the stack */
++	frame.pc = thread_saved_pc(p);
++	do {
++		int ret = unwind_frame(&frame);
++		if (ret < 0)
++			return 0;
++		if (!in_sched_functions(frame.pc))
++			return frame.pc;
++	} while (count ++ < 16);
++	return 0;
++}
+diff -rupN linux-2.6.35.11/arch/arm/kernel/setup.c linux-2.6.35.11-ts7500/arch/arm/kernel/setup.c
+--- linux-2.6.35.11/arch/arm/kernel/setup.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/setup.c	2011-03-14 11:18:24.000000000 -0400
+@@ -370,6 +370,7 @@ static struct machine_desc * __init setu
+ {
+ 	struct machine_desc *list;
+ 
++   //printk("setup_machine()\n");
+ 	/*
+ 	 * locate machine in the list of supported machines.
+ 	 */
+@@ -656,6 +657,7 @@ static void (*init_machine)(void) __init
+ 
+ static int __init customize_machine(void)
+ {
++   printk("customize_machine(), calling init_machine()\n");
+ 	/* customizes platform devices, or adds new ones */
+ 	if (init_machine)
+ 		init_machine();
+@@ -667,8 +669,10 @@ void __init setup_arch(char **cmdline_p)
+ {
+ 	struct tag *tags = (struct tag *)&init_tags;
+ 	struct machine_desc *mdesc;
+-	char *from = default_command_line;
++	char *from = default_command_line;               
+ 
++   //printk("setup_arch()\n");
++   
+ 	unwind_init();
+ 
+ 	setup_processor();
+@@ -726,6 +730,22 @@ void __init setup_arch(char **cmdline_p)
+ 	cpu_init();
+ 	tcm_init();
+ 
++#ifdef CONFIG_ARCH_STR9100
++	{
++		extern void __init str9100_early_init(void);
++
++		str9100_early_init();
++	}
++#endif
++
++#ifdef CONFIG_ARCH_STR8100
++	{
++		extern void __init str8100_early_init(void);
++
++		str8100_early_init();
++	}
++#endif   
++   
+ 	/*
+ 	 * Set up various architecture-specific pointers
+ 	 */
+@@ -760,9 +780,11 @@ subsys_initcall(topology_init);
+ 
+ #ifdef CONFIG_HAVE_PROC_CPU
+ static int __init proc_cpu_init(void)
+-{
++{   
+ 	struct proc_dir_entry *res;
+ 
++   printk("proc_cpu_init()\n");
++   
+ 	res = proc_mkdir("cpu", NULL);
+ 	if (!res)
+ 		return -ENOMEM;
+diff -rupN linux-2.6.35.11/arch/arm/kernel/setup.c.orig linux-2.6.35.11-ts7500/arch/arm/kernel/setup.c.orig
+--- linux-2.6.35.11/arch/arm/kernel/setup.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/setup.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,876 @@
++/*
++ *  linux/arch/arm/kernel/setup.c
++ *
++ *  Copyright (C) 1995-2001 Russell King
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/stddef.h>
++#include <linux/ioport.h>
++#include <linux/delay.h>
++#include <linux/utsname.h>
++#include <linux/initrd.h>
++#include <linux/console.h>
++#include <linux/bootmem.h>
++#include <linux/seq_file.h>
++#include <linux/screen_info.h>
++#include <linux/init.h>
++#include <linux/root_dev.h>
++#include <linux/cpu.h>
++#include <linux/interrupt.h>
++#include <linux/smp.h>
++#include <linux/fs.h>
++#include <linux/proc_fs.h>
++
++#include <asm/unified.h>
++#include <asm/cpu.h>
++#include <asm/cputype.h>
++#include <asm/elf.h>
++#include <asm/procinfo.h>
++#include <asm/sections.h>
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++#include <asm/cacheflush.h>
++#include <asm/cachetype.h>
++#include <asm/tlbflush.h>
++
++#include <asm/mach/arch.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/time.h>
++#include <asm/traps.h>
++#include <asm/unwind.h>
++
++#include "compat.h"
++#include "atags.h"
++#include "tcm.h"
++
++#ifndef MEM_SIZE
++#define MEM_SIZE	(16*1024*1024)
++#endif
++
++#if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
++char fpe_type[8];
++
++static int __init fpe_setup(char *line)
++{
++	memcpy(fpe_type, line, 8);
++	return 1;
++}
++
++__setup("fpe=", fpe_setup);
++#endif
++
++extern void paging_init(struct machine_desc *desc);
++extern void reboot_setup(char *str);
++
++unsigned int processor_id;
++EXPORT_SYMBOL(processor_id);
++unsigned int __machine_arch_type;
++EXPORT_SYMBOL(__machine_arch_type);
++unsigned int cacheid;
++EXPORT_SYMBOL(cacheid);
++
++unsigned int __atags_pointer __initdata;
++
++unsigned int system_rev;
++EXPORT_SYMBOL(system_rev);
++
++unsigned int system_serial_low;
++EXPORT_SYMBOL(system_serial_low);
++
++unsigned int system_serial_high;
++EXPORT_SYMBOL(system_serial_high);
++
++unsigned int elf_hwcap;
++EXPORT_SYMBOL(elf_hwcap);
++
++
++#ifdef MULTI_CPU
++struct processor processor;
++#endif
++#ifdef MULTI_TLB
++struct cpu_tlb_fns cpu_tlb;
++#endif
++#ifdef MULTI_USER
++struct cpu_user_fns cpu_user;
++#endif
++#ifdef MULTI_CACHE
++struct cpu_cache_fns cpu_cache;
++#endif
++#ifdef CONFIG_OUTER_CACHE
++struct outer_cache_fns outer_cache;
++EXPORT_SYMBOL(outer_cache);
++#endif
++
++struct stack {
++	u32 irq[3];
++	u32 abt[3];
++	u32 und[3];
++} ____cacheline_aligned;
++
++static struct stack stacks[NR_CPUS];
++
++char elf_platform[ELF_PLATFORM_SIZE];
++EXPORT_SYMBOL(elf_platform);
++
++static const char *cpu_name;
++static const char *machine_name;
++static char __initdata cmd_line[COMMAND_LINE_SIZE];
++
++static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
++static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
++#define ENDIANNESS ((char)endian_test.l)
++
++DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data);
++
++/*
++ * Standard memory resources
++ */
++static struct resource mem_res[] = {
++	{
++		.name = "Video RAM",
++		.start = 0,
++		.end = 0,
++		.flags = IORESOURCE_MEM
++	},
++	{
++		.name = "Kernel text",
++		.start = 0,
++		.end = 0,
++		.flags = IORESOURCE_MEM
++	},
++	{
++		.name = "Kernel data",
++		.start = 0,
++		.end = 0,
++		.flags = IORESOURCE_MEM
++	}
++};
++
++#define video_ram   mem_res[0]
++#define kernel_code mem_res[1]
++#define kernel_data mem_res[2]
++
++static struct resource io_res[] = {
++	{
++		.name = "reserved",
++		.start = 0x3bc,
++		.end = 0x3be,
++		.flags = IORESOURCE_IO | IORESOURCE_BUSY
++	},
++	{
++		.name = "reserved",
++		.start = 0x378,
++		.end = 0x37f,
++		.flags = IORESOURCE_IO | IORESOURCE_BUSY
++	},
++	{
++		.name = "reserved",
++		.start = 0x278,
++		.end = 0x27f,
++		.flags = IORESOURCE_IO | IORESOURCE_BUSY
++	}
++};
++
++#define lp0 io_res[0]
++#define lp1 io_res[1]
++#define lp2 io_res[2]
++
++static const char *proc_arch[] = {
++	"undefined/unknown",
++	"3",
++	"4",
++	"4T",
++	"5",
++	"5T",
++	"5TE",
++	"5TEJ",
++	"6TEJ",
++	"7",
++	"?(11)",
++	"?(12)",
++	"?(13)",
++	"?(14)",
++	"?(15)",
++	"?(16)",
++	"?(17)",
++};
++
++int cpu_architecture(void)
++{
++	int cpu_arch;
++
++	if ((read_cpuid_id() & 0x0008f000) == 0) {
++		cpu_arch = CPU_ARCH_UNKNOWN;
++	} else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
++		cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
++	} else if ((read_cpuid_id() & 0x00080000) == 0x00000000) {
++		cpu_arch = (read_cpuid_id() >> 16) & 7;
++		if (cpu_arch)
++			cpu_arch += CPU_ARCH_ARMv3;
++	} else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
++		unsigned int mmfr0;
++
++		/* Revised CPUID format. Read the Memory Model Feature
++		 * Register 0 and check for VMSAv7 or PMSAv7 */
++		asm("mrc	p15, 0, %0, c0, c1, 4"
++		    : "=r" (mmfr0));
++		if ((mmfr0 & 0x0000000f) == 0x00000003 ||
++		    (mmfr0 & 0x000000f0) == 0x00000030)
++			cpu_arch = CPU_ARCH_ARMv7;
++		else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
++			 (mmfr0 & 0x000000f0) == 0x00000020)
++			cpu_arch = CPU_ARCH_ARMv6;
++		else
++			cpu_arch = CPU_ARCH_UNKNOWN;
++	} else
++		cpu_arch = CPU_ARCH_UNKNOWN;
++
++	return cpu_arch;
++}
++
++static void __init cacheid_init(void)
++{
++	unsigned int cachetype = read_cpuid_cachetype();
++	unsigned int arch = cpu_architecture();
++
++	if (arch >= CPU_ARCH_ARMv6) {
++		if ((cachetype & (7 << 29)) == 4 << 29) {
++			/* ARMv7 register format */
++			cacheid = CACHEID_VIPT_NONALIASING;
++			if ((cachetype & (3 << 14)) == 1 << 14)
++				cacheid |= CACHEID_ASID_TAGGED;
++		} else if (cachetype & (1 << 23))
++			cacheid = CACHEID_VIPT_ALIASING;
++		else
++			cacheid = CACHEID_VIPT_NONALIASING;
++	} else {
++		cacheid = CACHEID_VIVT;
++	}
++
++	printk("CPU: %s data cache, %s instruction cache\n",
++		cache_is_vivt() ? "VIVT" :
++		cache_is_vipt_aliasing() ? "VIPT aliasing" :
++		cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown",
++		cache_is_vivt() ? "VIVT" :
++		icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
++		cache_is_vipt_aliasing() ? "VIPT aliasing" :
++		cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
++}
++
++/*
++ * These functions re-use the assembly code in head.S, which
++ * already provide the required functionality.
++ */
++extern struct proc_info_list *lookup_processor_type(unsigned int);
++extern struct machine_desc *lookup_machine_type(unsigned int);
++
++static void __init setup_processor(void)
++{
++	struct proc_info_list *list;
++
++	/*
++	 * locate processor in the list of supported processor
++	 * types.  The linker builds this table for us from the
++	 * entries in arch/arm/mm/proc-*.S
++	 */
++	list = lookup_processor_type(read_cpuid_id());
++	if (!list) {
++		printk("CPU configuration botched (ID %08x), unable "
++		       "to continue.\n", read_cpuid_id());
++		while (1);
++	}
++
++	cpu_name = list->cpu_name;
++
++#ifdef MULTI_CPU
++	processor = *list->proc;
++#endif
++#ifdef MULTI_TLB
++	cpu_tlb = *list->tlb;
++#endif
++#ifdef MULTI_USER
++	cpu_user = *list->user;
++#endif
++#ifdef MULTI_CACHE
++	cpu_cache = *list->cache;
++#endif
++
++	printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
++	       cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
++	       proc_arch[cpu_architecture()], cr_alignment);
++
++	sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
++	sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
++	elf_hwcap = list->elf_hwcap;
++#ifndef CONFIG_ARM_THUMB
++	elf_hwcap &= ~HWCAP_THUMB;
++#endif
++
++	cacheid_init();
++	cpu_proc_init();
++}
++
++/*
++ * cpu_init - initialise one CPU.
++ *
++ * cpu_init sets up the per-CPU stacks.
++ */
++void cpu_init(void)
++{
++	unsigned int cpu = smp_processor_id();
++	struct stack *stk = &stacks[cpu];
++
++	if (cpu >= NR_CPUS) {
++		printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
++		BUG();
++	}
++
++	/*
++	 * Define the placement constraint for the inline asm directive below.
++	 * In Thumb-2, msr with an immediate value is not allowed.
++	 */
++#ifdef CONFIG_THUMB2_KERNEL
++#define PLC	"r"
++#else
++#define PLC	"I"
++#endif
++
++	/*
++	 * setup stacks for re-entrant exception handlers
++	 */
++	__asm__ (
++	"msr	cpsr_c, %1\n\t"
++	"add	r14, %0, %2\n\t"
++	"mov	sp, r14\n\t"
++	"msr	cpsr_c, %3\n\t"
++	"add	r14, %0, %4\n\t"
++	"mov	sp, r14\n\t"
++	"msr	cpsr_c, %5\n\t"
++	"add	r14, %0, %6\n\t"
++	"mov	sp, r14\n\t"
++	"msr	cpsr_c, %7"
++	    :
++	    : "r" (stk),
++	      PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
++	      "I" (offsetof(struct stack, irq[0])),
++	      PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
++	      "I" (offsetof(struct stack, abt[0])),
++	      PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE),
++	      "I" (offsetof(struct stack, und[0])),
++	      PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
++	    : "r14");
++}
++
++static struct machine_desc * __init setup_machine(unsigned int nr)
++{
++	struct machine_desc *list;
++
++	/*
++	 * locate machine in the list of supported machines.
++	 */
++	list = lookup_machine_type(nr);
++	if (!list) {
++		printk("Machine configuration botched (nr %d), unable "
++		       "to continue.\n", nr);
++		while (1);
++	}
++
++	printk("Machine: %s\n", list->name);
++
++	return list;
++}
++
++static int __init arm_add_memory(unsigned long start, unsigned long size)
++{
++	struct membank *bank = &meminfo.bank[meminfo.nr_banks];
++
++	if (meminfo.nr_banks >= NR_BANKS) {
++		printk(KERN_CRIT "NR_BANKS too low, "
++			"ignoring memory at %#lx\n", start);
++		return -EINVAL;
++	}
++
++	/*
++	 * Ensure that start/size are aligned to a page boundary.
++	 * Size is appropriately rounded down, start is rounded up.
++	 */
++	size -= start & ~PAGE_MASK;
++	bank->start = PAGE_ALIGN(start);
++	bank->size  = size & PAGE_MASK;
++	bank->node  = PHYS_TO_NID(start);
++
++	/*
++	 * Check whether this memory region has non-zero size or
++	 * invalid node number.
++	 */
++	if (bank->size == 0 || bank->node >= MAX_NUMNODES)
++		return -EINVAL;
++
++	meminfo.nr_banks++;
++	return 0;
++}
++
++/*
++ * Pick out the memory size.  We look for mem=size at start,
++ * where start and size are "size[KkMm]"
++ */
++static int __init early_mem(char *p)
++{
++	static int usermem __initdata = 0;
++	unsigned long size, start;
++	char *endp;
++
++	/*
++	 * If the user specifies memory size, we
++	 * blow away any automatically generated
++	 * size.
++	 */
++	if (usermem == 0) {
++		usermem = 1;
++		meminfo.nr_banks = 0;
++	}
++
++	start = PHYS_OFFSET;
++	size  = memparse(p, &endp);
++	if (*endp == '@')
++		start = memparse(endp + 1, NULL);
++
++	arm_add_memory(start, size);
++
++	return 0;
++}
++early_param("mem", early_mem);
++
++static void __init
++setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
++{
++#ifdef CONFIG_BLK_DEV_RAM
++	extern int rd_size, rd_image_start, rd_prompt, rd_doload;
++
++	rd_image_start = image_start;
++	rd_prompt = prompt;
++	rd_doload = doload;
++
++	if (rd_sz)
++		rd_size = rd_sz;
++#endif
++}
++
++static void __init
++request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
++{
++	struct resource *res;
++	int i;
++
++	kernel_code.start   = virt_to_phys(_text);
++	kernel_code.end     = virt_to_phys(_etext - 1);
++	kernel_data.start   = virt_to_phys(_data);
++	kernel_data.end     = virt_to_phys(_end - 1);
++
++	for (i = 0; i < mi->nr_banks; i++) {
++		if (mi->bank[i].size == 0)
++			continue;
++
++		res = alloc_bootmem_low(sizeof(*res));
++		res->name  = "System RAM";
++		res->start = mi->bank[i].start;
++		res->end   = mi->bank[i].start + mi->bank[i].size - 1;
++		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
++
++		request_resource(&iomem_resource, res);
++
++		if (kernel_code.start >= res->start &&
++		    kernel_code.end <= res->end)
++			request_resource(res, &kernel_code);
++		if (kernel_data.start >= res->start &&
++		    kernel_data.end <= res->end)
++			request_resource(res, &kernel_data);
++	}
++
++	if (mdesc->video_start) {
++		video_ram.start = mdesc->video_start;
++		video_ram.end   = mdesc->video_end;
++		request_resource(&iomem_resource, &video_ram);
++	}
++
++	/*
++	 * Some machines don't have the possibility of ever
++	 * possessing lp0, lp1 or lp2
++	 */
++	if (mdesc->reserve_lp0)
++		request_resource(&ioport_resource, &lp0);
++	if (mdesc->reserve_lp1)
++		request_resource(&ioport_resource, &lp1);
++	if (mdesc->reserve_lp2)
++		request_resource(&ioport_resource, &lp2);
++}
++
++/*
++ *  Tag parsing.
++ *
++ * This is the new way of passing data to the kernel at boot time.  Rather
++ * than passing a fixed inflexible structure to the kernel, we pass a list
++ * of variable-sized tags to the kernel.  The first tag must be a ATAG_CORE
++ * tag for the list to be recognised (to distinguish the tagged list from
++ * a param_struct).  The list is terminated with a zero-length tag (this tag
++ * is not parsed in any way).
++ */
++static int __init parse_tag_core(const struct tag *tag)
++{
++	if (tag->hdr.size > 2) {
++		if ((tag->u.core.flags & 1) == 0)
++			root_mountflags &= ~MS_RDONLY;
++		ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
++	}
++	return 0;
++}
++
++__tagtable(ATAG_CORE, parse_tag_core);
++
++static int __init parse_tag_mem32(const struct tag *tag)
++{
++	return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
++}
++
++__tagtable(ATAG_MEM, parse_tag_mem32);
++
++#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
++struct screen_info screen_info = {
++ .orig_video_lines	= 30,
++ .orig_video_cols	= 80,
++ .orig_video_mode	= 0,
++ .orig_video_ega_bx	= 0,
++ .orig_video_isVGA	= 1,
++ .orig_video_points	= 8
++};
++
++static int __init parse_tag_videotext(const struct tag *tag)
++{
++	screen_info.orig_x            = tag->u.videotext.x;
++	screen_info.orig_y            = tag->u.videotext.y;
++	screen_info.orig_video_page   = tag->u.videotext.video_page;
++	screen_info.orig_video_mode   = tag->u.videotext.video_mode;
++	screen_info.orig_video_cols   = tag->u.videotext.video_cols;
++	screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
++	screen_info.orig_video_lines  = tag->u.videotext.video_lines;
++	screen_info.orig_video_isVGA  = tag->u.videotext.video_isvga;
++	screen_info.orig_video_points = tag->u.videotext.video_points;
++	return 0;
++}
++
++__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
++#endif
++
++static int __init parse_tag_ramdisk(const struct tag *tag)
++{
++	setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
++		      (tag->u.ramdisk.flags & 2) == 0,
++		      tag->u.ramdisk.start, tag->u.ramdisk.size);
++	return 0;
++}
++
++__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
++
++static int __init parse_tag_serialnr(const struct tag *tag)
++{
++	system_serial_low = tag->u.serialnr.low;
++	system_serial_high = tag->u.serialnr.high;
++	return 0;
++}
++
++__tagtable(ATAG_SERIAL, parse_tag_serialnr);
++
++static int __init parse_tag_revision(const struct tag *tag)
++{
++	system_rev = tag->u.revision.rev;
++	return 0;
++}
++
++__tagtable(ATAG_REVISION, parse_tag_revision);
++
++#ifndef CONFIG_CMDLINE_FORCE
++static int __init parse_tag_cmdline(const struct tag *tag)
++{
++	strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
++	return 0;
++}
++
++__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
++#endif /* CONFIG_CMDLINE_FORCE */
++
++/*
++ * Scan the tag table for this tag, and call its parse function.
++ * The tag table is built by the linker from all the __tagtable
++ * declarations.
++ */
++static int __init parse_tag(const struct tag *tag)
++{
++	extern struct tagtable __tagtable_begin, __tagtable_end;
++	struct tagtable *t;
++
++	for (t = &__tagtable_begin; t < &__tagtable_end; t++)
++		if (tag->hdr.tag == t->tag) {
++			t->parse(tag);
++			break;
++		}
++
++	return t < &__tagtable_end;
++}
++
++/*
++ * Parse all tags in the list, checking both the global and architecture
++ * specific tag tables.
++ */
++static void __init parse_tags(const struct tag *t)
++{
++	for (; t->hdr.size; t = tag_next(t))
++		if (!parse_tag(t))
++			printk(KERN_WARNING
++				"Ignoring unrecognised tag 0x%08x\n",
++				t->hdr.tag);
++}
++
++/*
++ * This holds our defaults.
++ */
++static struct init_tags {
++	struct tag_header hdr1;
++	struct tag_core   core;
++	struct tag_header hdr2;
++	struct tag_mem32  mem;
++	struct tag_header hdr3;
++} init_tags __initdata = {
++	{ tag_size(tag_core), ATAG_CORE },
++	{ 1, PAGE_SIZE, 0xff },
++	{ tag_size(tag_mem32), ATAG_MEM },
++	{ MEM_SIZE, PHYS_OFFSET },
++	{ 0, ATAG_NONE }
++};
++
++static void (*init_machine)(void) __initdata;
++
++static int __init customize_machine(void)
++{
++	/* customizes platform devices, or adds new ones */
++	if (init_machine)
++		init_machine();
++	return 0;
++}
++arch_initcall(customize_machine);
++
++void __init setup_arch(char **cmdline_p)
++{
++	struct tag *tags = (struct tag *)&init_tags;
++	struct machine_desc *mdesc;
++	char *from = default_command_line;
++
++	unwind_init();
++
++	setup_processor();
++	mdesc = setup_machine(machine_arch_type);
++	machine_name = mdesc->name;
++
++	if (mdesc->soft_reboot)
++		reboot_setup("s");
++
++	if (__atags_pointer)
++		tags = phys_to_virt(__atags_pointer);
++	else if (mdesc->boot_params)
++		tags = phys_to_virt(mdesc->boot_params);
++
++	/*
++	 * If we have the old style parameters, convert them to
++	 * a tag list.
++	 */
++	if (tags->hdr.tag != ATAG_CORE)
++		convert_to_tag_list(tags);
++	if (tags->hdr.tag != ATAG_CORE)
++		tags = (struct tag *)&init_tags;
++
++	if (mdesc->fixup)
++		mdesc->fixup(mdesc, tags, &from, &meminfo);
++
++	if (tags->hdr.tag == ATAG_CORE) {
++		if (meminfo.nr_banks != 0)
++			squash_mem_tags(tags);
++		save_atags(tags);
++		parse_tags(tags);
++	}
++
++	init_mm.start_code = (unsigned long) _text;
++	init_mm.end_code   = (unsigned long) _etext;
++	init_mm.end_data   = (unsigned long) _edata;
++	init_mm.brk	   = (unsigned long) _end;
++
++	/* parse_early_param needs a boot_command_line */
++	strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
++
++	/* populate cmd_line too for later use, preserving boot_command_line */
++	strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
++	*cmdline_p = cmd_line;
++
++	parse_early_param();
++
++	paging_init(mdesc);
++	request_standard_resources(&meminfo, mdesc);
++
++#ifdef CONFIG_SMP
++	smp_init_cpus();
++#endif
++
++	cpu_init();
++	tcm_init();
++
++	/*
++	 * Set up various architecture-specific pointers
++	 */
++	init_arch_irq = mdesc->init_irq;
++	system_timer = mdesc->timer;
++	init_machine = mdesc->init_machine;
++
++#ifdef CONFIG_VT
++#if defined(CONFIG_VGA_CONSOLE)
++	conswitchp = &vga_con;
++#elif defined(CONFIG_DUMMY_CONSOLE)
++	conswitchp = &dummy_con;
++#endif
++#endif
++	early_trap_init();
++}
++
++
++static int __init topology_init(void)
++{
++	int cpu;
++
++	for_each_possible_cpu(cpu) {
++		struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu);
++		cpuinfo->cpu.hotpluggable = 1;
++		register_cpu(&cpuinfo->cpu, cpu);
++	}
++
++	return 0;
++}
++subsys_initcall(topology_init);
++
++#ifdef CONFIG_HAVE_PROC_CPU
++static int __init proc_cpu_init(void)
++{
++	struct proc_dir_entry *res;
++
++	res = proc_mkdir("cpu", NULL);
++	if (!res)
++		return -ENOMEM;
++	return 0;
++}
++fs_initcall(proc_cpu_init);
++#endif
++
++static const char *hwcap_str[] = {
++	"swp",
++	"half",
++	"thumb",
++	"26bit",
++	"fastmult",
++	"fpa",
++	"vfp",
++	"edsp",
++	"java",
++	"iwmmxt",
++	"crunch",
++	"thumbee",
++	"neon",
++	"vfpv3",
++	"vfpv3d16",
++	NULL
++};
++
++static int c_show(struct seq_file *m, void *v)
++{
++	int i;
++
++	seq_printf(m, "Processor\t: %s rev %d (%s)\n",
++		   cpu_name, read_cpuid_id() & 15, elf_platform);
++
++#if defined(CONFIG_SMP)
++	for_each_online_cpu(i) {
++		/*
++		 * glibc reads /proc/cpuinfo to determine the number of
++		 * online processors, looking for lines beginning with
++		 * "processor".  Give glibc what it expects.
++		 */
++		seq_printf(m, "processor\t: %d\n", i);
++		seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
++			   per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
++			   (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
++	}
++#else /* CONFIG_SMP */
++	seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
++		   loops_per_jiffy / (500000/HZ),
++		   (loops_per_jiffy / (5000/HZ)) % 100);
++#endif
++
++	/* dump out the processor features */
++	seq_puts(m, "Features\t: ");
++
++	for (i = 0; hwcap_str[i]; i++)
++		if (elf_hwcap & (1 << i))
++			seq_printf(m, "%s ", hwcap_str[i]);
++
++	seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
++	seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
++
++	if ((read_cpuid_id() & 0x0008f000) == 0x00000000) {
++		/* pre-ARM7 */
++		seq_printf(m, "CPU part\t: %07x\n", read_cpuid_id() >> 4);
++	} else {
++		if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
++			/* ARM7 */
++			seq_printf(m, "CPU variant\t: 0x%02x\n",
++				   (read_cpuid_id() >> 16) & 127);
++		} else {
++			/* post-ARM7 */
++			seq_printf(m, "CPU variant\t: 0x%x\n",
++				   (read_cpuid_id() >> 20) & 15);
++		}
++		seq_printf(m, "CPU part\t: 0x%03x\n",
++			   (read_cpuid_id() >> 4) & 0xfff);
++	}
++	seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
++
++	seq_puts(m, "\n");
++
++	seq_printf(m, "Hardware\t: %s\n", machine_name);
++	seq_printf(m, "Revision\t: %04x\n", system_rev);
++	seq_printf(m, "Serial\t\t: %08x%08x\n",
++		   system_serial_high, system_serial_low);
++
++	return 0;
++}
++
++static void *c_start(struct seq_file *m, loff_t *pos)
++{
++	return *pos < 1 ? (void *)1 : NULL;
++}
++
++static void *c_next(struct seq_file *m, void *v, loff_t *pos)
++{
++	++*pos;
++	return NULL;
++}
++
++static void c_stop(struct seq_file *m, void *v)
++{
++}
++
++const struct seq_operations cpuinfo_op = {
++	.start	= c_start,
++	.next	= c_next,
++	.stop	= c_stop,
++	.show	= c_show
++};
+diff -rupN linux-2.6.35.11/arch/arm/kernel/traps.c linux-2.6.35.11-ts7500/arch/arm/kernel/traps.c
+--- linux-2.6.35.11/arch/arm/kernel/traps.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/traps.c	2011-03-14 11:18:24.000000000 -0400
+@@ -467,7 +467,7 @@ asmlinkage int arm_syscall(int no, struc
+ {
+ 	struct thread_info *thread = current_thread_info();
+ 	siginfo_t info;
+-
++	
+ 	if ((no >> 16) != (__ARM_NR_BASE>> 16))
+ 		return bad_syscall(no, regs);
+ 
+diff -rupN linux-2.6.35.11/arch/arm/kernel/traps.c.orig linux-2.6.35.11-ts7500/arch/arm/kernel/traps.c.orig
+--- linux-2.6.35.11/arch/arm/kernel/traps.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/traps.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,774 @@
++/*
++ *  linux/arch/arm/kernel/traps.c
++ *
++ *  Copyright (C) 1995-2009 Russell King
++ *  Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  'traps.c' handles hardware exceptions after we have saved some state in
++ *  'linux/arch/arm/lib/traps.S'.  Mostly a debugging aid, but will probably
++ *  kill the offending process.
++ */
++#include <linux/signal.h>
++#include <linux/personality.h>
++#include <linux/kallsyms.h>
++#include <linux/spinlock.h>
++#include <linux/uaccess.h>
++#include <linux/hardirq.h>
++#include <linux/kdebug.h>
++#include <linux/module.h>
++#include <linux/kexec.h>
++#include <linux/delay.h>
++#include <linux/init.h>
++
++#include <asm/atomic.h>
++#include <asm/cacheflush.h>
++#include <asm/system.h>
++#include <asm/unistd.h>
++#include <asm/traps.h>
++#include <asm/unwind.h>
++
++#include "ptrace.h"
++#include "signal.h"
++
++static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
++
++#ifdef CONFIG_DEBUG_USER
++unsigned int user_debug;
++
++static int __init user_debug_setup(char *str)
++{
++	get_option(&str, &user_debug);
++	return 1;
++}
++__setup("user_debug=", user_debug_setup);
++#endif
++
++static void dump_mem(const char *, const char *, unsigned long, unsigned long);
++
++void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
++{
++#ifdef CONFIG_KALLSYMS
++	char sym1[KSYM_SYMBOL_LEN], sym2[KSYM_SYMBOL_LEN];
++	sprint_symbol(sym1, where);
++	sprint_symbol(sym2, from);
++	printk("[<%08lx>] (%s) from [<%08lx>] (%s)\n", where, sym1, from, sym2);
++#else
++	printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
++#endif
++
++	if (in_exception_text(where))
++		dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
++}
++
++#ifndef CONFIG_ARM_UNWIND
++/*
++ * Stack pointers should always be within the kernels view of
++ * physical memory.  If it is not there, then we can't dump
++ * out any information relating to the stack.
++ */
++static int verify_stack(unsigned long sp)
++{
++	if (sp < PAGE_OFFSET ||
++	    (sp > (unsigned long)high_memory && high_memory != NULL))
++		return -EFAULT;
++
++	return 0;
++}
++#endif
++
++/*
++ * Dump out the contents of some memory nicely...
++ */
++static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
++		     unsigned long top)
++{
++	unsigned long first;
++	mm_segment_t fs;
++	int i;
++
++	/*
++	 * We need to switch to kernel mode so that we can use __get_user
++	 * to safely read from kernel space.  Note that we now dump the
++	 * code first, just in case the backtrace kills us.
++	 */
++	fs = get_fs();
++	set_fs(KERNEL_DS);
++
++	printk("%s%s(0x%08lx to 0x%08lx)\n", lvl, str, bottom, top);
++
++	for (first = bottom & ~31; first < top; first += 32) {
++		unsigned long p;
++		char str[sizeof(" 12345678") * 8 + 1];
++
++		memset(str, ' ', sizeof(str));
++		str[sizeof(str) - 1] = '\0';
++
++		for (p = first, i = 0; i < 8 && p < top; i++, p += 4) {
++			if (p >= bottom && p < top) {
++				unsigned long val;
++				if (__get_user(val, (unsigned long *)p) == 0)
++					sprintf(str + i * 9, " %08lx", val);
++				else
++					sprintf(str + i * 9, " ????????");
++			}
++		}
++		printk("%s%04lx:%s\n", lvl, first & 0xffff, str);
++	}
++
++	set_fs(fs);
++}
++
++static void dump_instr(const char *lvl, struct pt_regs *regs)
++{
++	unsigned long addr = instruction_pointer(regs);
++	const int thumb = thumb_mode(regs);
++	const int width = thumb ? 4 : 8;
++	mm_segment_t fs;
++	char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
++	int i;
++
++	/*
++	 * We need to switch to kernel mode so that we can use __get_user
++	 * to safely read from kernel space.  Note that we now dump the
++	 * code first, just in case the backtrace kills us.
++	 */
++	fs = get_fs();
++	set_fs(KERNEL_DS);
++
++	for (i = -4; i < 1; i++) {
++		unsigned int val, bad;
++
++		if (thumb)
++			bad = __get_user(val, &((u16 *)addr)[i]);
++		else
++			bad = __get_user(val, &((u32 *)addr)[i]);
++
++		if (!bad)
++			p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
++					width, val);
++		else {
++			p += sprintf(p, "bad PC value");
++			break;
++		}
++	}
++	printk("%sCode: %s\n", lvl, str);
++
++	set_fs(fs);
++}
++
++#ifdef CONFIG_ARM_UNWIND
++static inline void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
++{
++	unwind_backtrace(regs, tsk);
++}
++#else
++static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
++{
++	unsigned int fp, mode;
++	int ok = 1;
++
++	printk("Backtrace: ");
++
++	if (!tsk)
++		tsk = current;
++
++	if (regs) {
++		fp = regs->ARM_fp;
++		mode = processor_mode(regs);
++	} else if (tsk != current) {
++		fp = thread_saved_fp(tsk);
++		mode = 0x10;
++	} else {
++		asm("mov %0, fp" : "=r" (fp) : : "cc");
++		mode = 0x10;
++	}
++
++	if (!fp) {
++		printk("no frame pointer");
++		ok = 0;
++	} else if (verify_stack(fp)) {
++		printk("invalid frame pointer 0x%08x", fp);
++		ok = 0;
++	} else if (fp < (unsigned long)end_of_stack(tsk))
++		printk("frame pointer underflow");
++	printk("\n");
++
++	if (ok)
++		c_backtrace(fp, mode);
++}
++#endif
++
++void dump_stack(void)
++{
++	dump_backtrace(NULL, NULL);
++}
++
++EXPORT_SYMBOL(dump_stack);
++
++void show_stack(struct task_struct *tsk, unsigned long *sp)
++{
++	dump_backtrace(NULL, tsk);
++	barrier();
++}
++
++#ifdef CONFIG_PREEMPT
++#define S_PREEMPT " PREEMPT"
++#else
++#define S_PREEMPT ""
++#endif
++#ifdef CONFIG_SMP
++#define S_SMP " SMP"
++#else
++#define S_SMP ""
++#endif
++
++static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
++{
++	struct task_struct *tsk = thread->task;
++	static int die_counter;
++	int ret;
++
++	printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
++	       str, err, ++die_counter);
++	sysfs_printk_last_file();
++
++	/* trap and error numbers are mostly meaningless on ARM */
++	ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
++	if (ret == NOTIFY_STOP)
++		return ret;
++
++	print_modules();
++	__show_regs(regs);
++	printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
++		TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);
++
++	if (!user_mode(regs) || in_interrupt()) {
++		dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
++			 THREAD_SIZE + (unsigned long)task_stack_page(tsk));
++		dump_backtrace(regs, tsk);
++		dump_instr(KERN_EMERG, regs);
++	}
++
++	return ret;
++}
++
++DEFINE_SPINLOCK(die_lock);
++
++/*
++ * This function is protected against re-entrancy.
++ */
++void die(const char *str, struct pt_regs *regs, int err)
++{
++	struct thread_info *thread = current_thread_info();
++	int ret;
++
++	oops_enter();
++
++	spin_lock_irq(&die_lock);
++	console_verbose();
++	bust_spinlocks(1);
++	ret = __die(str, err, thread, regs);
++
++	if (regs && kexec_should_crash(thread->task))
++		crash_kexec(regs);
++
++	bust_spinlocks(0);
++	add_taint(TAINT_DIE);
++	spin_unlock_irq(&die_lock);
++	oops_exit();
++
++	if (in_interrupt())
++		panic("Fatal exception in interrupt");
++	if (panic_on_oops)
++		panic("Fatal exception");
++	if (ret != NOTIFY_STOP)
++		do_exit(SIGSEGV);
++}
++
++void arm_notify_die(const char *str, struct pt_regs *regs,
++		struct siginfo *info, unsigned long err, unsigned long trap)
++{
++	if (user_mode(regs)) {
++		current->thread.error_code = err;
++		current->thread.trap_no = trap;
++
++		force_sig_info(info->si_signo, info, current);
++	} else {
++		die(str, regs, err);
++	}
++}
++
++static LIST_HEAD(undef_hook);
++static DEFINE_SPINLOCK(undef_lock);
++
++void register_undef_hook(struct undef_hook *hook)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&undef_lock, flags);
++	list_add(&hook->node, &undef_hook);
++	spin_unlock_irqrestore(&undef_lock, flags);
++}
++
++void unregister_undef_hook(struct undef_hook *hook)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&undef_lock, flags);
++	list_del(&hook->node);
++	spin_unlock_irqrestore(&undef_lock, flags);
++}
++
++static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
++{
++	struct undef_hook *hook;
++	unsigned long flags;
++	int (*fn)(struct pt_regs *regs, unsigned int instr) = NULL;
++
++	spin_lock_irqsave(&undef_lock, flags);
++	list_for_each_entry(hook, &undef_hook, node)
++		if ((instr & hook->instr_mask) == hook->instr_val &&
++		    (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val)
++			fn = hook->fn;
++	spin_unlock_irqrestore(&undef_lock, flags);
++
++	return fn ? fn(regs, instr) : 1;
++}
++
++asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
++{
++	unsigned int correction = thumb_mode(regs) ? 2 : 4;
++	unsigned int instr;
++	siginfo_t info;
++	void __user *pc;
++
++	/*
++	 * According to the ARM ARM, PC is 2 or 4 bytes ahead,
++	 * depending whether we're in Thumb mode or not.
++	 * Correct this offset.
++	 */
++	regs->ARM_pc -= correction;
++
++	pc = (void __user *)instruction_pointer(regs);
++
++	if (processor_mode(regs) == SVC_MODE) {
++		instr = *(u32 *) pc;
++	} else if (thumb_mode(regs)) {
++		get_user(instr, (u16 __user *)pc);
++	} else {
++		get_user(instr, (u32 __user *)pc);
++	}
++
++	if (call_undef_hook(regs, instr) == 0)
++		return;
++
++#ifdef CONFIG_DEBUG_USER
++	if (user_debug & UDBG_UNDEFINED) {
++		printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
++			current->comm, task_pid_nr(current), pc);
++		dump_instr(KERN_INFO, regs);
++	}
++#endif
++
++	info.si_signo = SIGILL;
++	info.si_errno = 0;
++	info.si_code  = ILL_ILLOPC;
++	info.si_addr  = pc;
++
++	arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6);
++}
++
++asmlinkage void do_unexp_fiq (struct pt_regs *regs)
++{
++	printk("Hmm.  Unexpected FIQ received, but trying to continue\n");
++	printk("You may have a hardware problem...\n");
++}
++
++/*
++ * bad_mode handles the impossible case in the vectors.  If you see one of
++ * these, then it's extremely serious, and could mean you have buggy hardware.
++ * It never returns, and never tries to sync.  We hope that we can at least
++ * dump out some state information...
++ */
++asmlinkage void bad_mode(struct pt_regs *regs, int reason)
++{
++	console_verbose();
++
++	printk(KERN_CRIT "Bad mode in %s handler detected\n", handler[reason]);
++
++	die("Oops - bad mode", regs, 0);
++	local_irq_disable();
++	panic("bad mode");
++}
++
++static int bad_syscall(int n, struct pt_regs *regs)
++{
++	struct thread_info *thread = current_thread_info();
++	siginfo_t info;
++
++	if (current->personality != PER_LINUX &&
++	    current->personality != PER_LINUX_32BIT &&
++	    thread->exec_domain->handler) {
++		thread->exec_domain->handler(n, regs);
++		return regs->ARM_r0;
++	}
++
++#ifdef CONFIG_DEBUG_USER
++	if (user_debug & UDBG_SYSCALL) {
++		printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
++			task_pid_nr(current), current->comm, n);
++		dump_instr(KERN_ERR, regs);
++	}
++#endif
++
++	info.si_signo = SIGILL;
++	info.si_errno = 0;
++	info.si_code  = ILL_ILLTRP;
++	info.si_addr  = (void __user *)instruction_pointer(regs) -
++			 (thumb_mode(regs) ? 2 : 4);
++
++	arm_notify_die("Oops - bad syscall", regs, &info, n, 0);
++
++	return regs->ARM_r0;
++}
++
++static inline void
++do_cache_op(unsigned long start, unsigned long end, int flags)
++{
++	struct mm_struct *mm = current->active_mm;
++	struct vm_area_struct *vma;
++
++	if (end < start || flags)
++		return;
++
++	down_read(&mm->mmap_sem);
++	vma = find_vma(mm, start);
++	if (vma && vma->vm_start < end) {
++		if (start < vma->vm_start)
++			start = vma->vm_start;
++		if (end > vma->vm_end)
++			end = vma->vm_end;
++
++		flush_cache_user_range(vma, start, end);
++	}
++	up_read(&mm->mmap_sem);
++}
++
++/*
++ * Handle all unrecognised system calls.
++ *  0x9f0000 - 0x9fffff are some more esoteric system calls
++ */
++#define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE)
++asmlinkage int arm_syscall(int no, struct pt_regs *regs)
++{
++	struct thread_info *thread = current_thread_info();
++	siginfo_t info;
++
++	if ((no >> 16) != (__ARM_NR_BASE>> 16))
++		return bad_syscall(no, regs);
++
++	switch (no & 0xffff) {
++	case 0: /* branch through 0 */
++		info.si_signo = SIGSEGV;
++		info.si_errno = 0;
++		info.si_code  = SEGV_MAPERR;
++		info.si_addr  = NULL;
++
++		arm_notify_die("branch through zero", regs, &info, 0, 0);
++		return 0;
++
++	case NR(breakpoint): /* SWI BREAK_POINT */
++		regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
++		ptrace_break(current, regs);
++		return regs->ARM_r0;
++
++	/*
++	 * Flush a region from virtual address 'r0' to virtual address 'r1'
++	 * _exclusive_.  There is no alignment requirement on either address;
++	 * user space does not need to know the hardware cache layout.
++	 *
++	 * r2 contains flags.  It should ALWAYS be passed as ZERO until it
++	 * is defined to be something else.  For now we ignore it, but may
++	 * the fires of hell burn in your belly if you break this rule. ;)
++	 *
++	 * (at a later date, we may want to allow this call to not flush
++	 * various aspects of the cache.  Passing '0' will guarantee that
++	 * everything necessary gets flushed to maintain consistency in
++	 * the specified region).
++	 */
++	case NR(cacheflush):
++		do_cache_op(regs->ARM_r0, regs->ARM_r1, regs->ARM_r2);
++		return 0;
++
++	case NR(usr26):
++		if (!(elf_hwcap & HWCAP_26BIT))
++			break;
++		regs->ARM_cpsr &= ~MODE32_BIT;
++		return regs->ARM_r0;
++
++	case NR(usr32):
++		if (!(elf_hwcap & HWCAP_26BIT))
++			break;
++		regs->ARM_cpsr |= MODE32_BIT;
++		return regs->ARM_r0;
++
++	case NR(set_tls):
++		thread->tp_value = regs->ARM_r0;
++#if defined(CONFIG_HAS_TLS_REG)
++		asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) );
++#elif !defined(CONFIG_TLS_REG_EMUL)
++		/*
++		 * User space must never try to access this directly.
++		 * Expect your app to break eventually if you do so.
++		 * The user helper at 0xffff0fe0 must be used instead.
++		 * (see entry-armv.S for details)
++		 */
++		*((unsigned int *)0xffff0ff0) = regs->ARM_r0;
++#endif
++		return 0;
++
++#ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG
++	/*
++	 * Atomically store r1 in *r2 if *r2 is equal to r0 for user space.
++	 * Return zero in r0 if *MEM was changed or non-zero if no exchange
++	 * happened.  Also set the user C flag accordingly.
++	 * If access permissions have to be fixed up then non-zero is
++	 * returned and the operation has to be re-attempted.
++	 *
++	 * *NOTE*: This is a ghost syscall private to the kernel.  Only the
++	 * __kuser_cmpxchg code in entry-armv.S should be aware of its
++	 * existence.  Don't ever use this from user code.
++	 */
++	case NR(cmpxchg):
++	for (;;) {
++		extern void do_DataAbort(unsigned long addr, unsigned int fsr,
++					 struct pt_regs *regs);
++		unsigned long val;
++		unsigned long addr = regs->ARM_r2;
++		struct mm_struct *mm = current->mm;
++		pgd_t *pgd; pmd_t *pmd; pte_t *pte;
++		spinlock_t *ptl;
++
++		regs->ARM_cpsr &= ~PSR_C_BIT;
++		down_read(&mm->mmap_sem);
++		pgd = pgd_offset(mm, addr);
++		if (!pgd_present(*pgd))
++			goto bad_access;
++		pmd = pmd_offset(pgd, addr);
++		if (!pmd_present(*pmd))
++			goto bad_access;
++		pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
++		if (!pte_present(*pte) || !pte_dirty(*pte)) {
++			pte_unmap_unlock(pte, ptl);
++			goto bad_access;
++		}
++		val = *(unsigned long *)addr;
++		val -= regs->ARM_r0;
++		if (val == 0) {
++			*(unsigned long *)addr = regs->ARM_r1;
++			regs->ARM_cpsr |= PSR_C_BIT;
++		}
++		pte_unmap_unlock(pte, ptl);
++		up_read(&mm->mmap_sem);
++		return val;
++
++		bad_access:
++		up_read(&mm->mmap_sem);
++		/* simulate a write access fault */
++		do_DataAbort(addr, 15 + (1 << 11), regs);
++	}
++#endif
++
++	default:
++		/* Calls 9f00xx..9f07ff are defined to return -ENOSYS
++		   if not implemented, rather than raising SIGILL.  This
++		   way the calling program can gracefully determine whether
++		   a feature is supported.  */
++		if ((no & 0xffff) <= 0x7ff)
++			return -ENOSYS;
++		break;
++	}
++#ifdef CONFIG_DEBUG_USER
++	/*
++	 * experience shows that these seem to indicate that
++	 * something catastrophic has happened
++	 */
++	if (user_debug & UDBG_SYSCALL) {
++		printk("[%d] %s: arm syscall %d\n",
++		       task_pid_nr(current), current->comm, no);
++		dump_instr("", regs);
++		if (user_mode(regs)) {
++			__show_regs(regs);
++			c_backtrace(regs->ARM_fp, processor_mode(regs));
++		}
++	}
++#endif
++	info.si_signo = SIGILL;
++	info.si_errno = 0;
++	info.si_code  = ILL_ILLTRP;
++	info.si_addr  = (void __user *)instruction_pointer(regs) -
++			 (thumb_mode(regs) ? 2 : 4);
++
++	arm_notify_die("Oops - bad syscall(2)", regs, &info, no, 0);
++	return 0;
++}
++
++#ifdef CONFIG_TLS_REG_EMUL
++
++/*
++ * We might be running on an ARMv6+ processor which should have the TLS
++ * register but for some reason we can't use it, or maybe an SMP system
++ * using a pre-ARMv6 processor (there are apparently a few prototypes like
++ * that in existence) and therefore access to that register must be
++ * emulated.
++ */
++
++static int get_tp_trap(struct pt_regs *regs, unsigned int instr)
++{
++	int reg = (instr >> 12) & 15;
++	if (reg == 15)
++		return 1;
++	regs->uregs[reg] = current_thread_info()->tp_value;
++	regs->ARM_pc += 4;
++	return 0;
++}
++
++static struct undef_hook arm_mrc_hook = {
++	.instr_mask	= 0x0fff0fff,
++	.instr_val	= 0x0e1d0f70,
++	.cpsr_mask	= PSR_T_BIT,
++	.cpsr_val	= 0,
++	.fn		= get_tp_trap,
++};
++
++static int __init arm_mrc_hook_init(void)
++{
++	register_undef_hook(&arm_mrc_hook);
++	return 0;
++}
++
++late_initcall(arm_mrc_hook_init);
++
++#endif
++
++void __bad_xchg(volatile void *ptr, int size)
++{
++	printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
++		__builtin_return_address(0), ptr, size);
++	BUG();
++}
++EXPORT_SYMBOL(__bad_xchg);
++
++/*
++ * A data abort trap was taken, but we did not handle the instruction.
++ * Try to abort the user program, or panic if it was the kernel.
++ */
++asmlinkage void
++baddataabort(int code, unsigned long instr, struct pt_regs *regs)
++{
++	unsigned long addr = instruction_pointer(regs);
++	siginfo_t info;
++
++#ifdef CONFIG_DEBUG_USER
++	if (user_debug & UDBG_BADABORT) {
++		printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
++			task_pid_nr(current), current->comm, code, instr);
++		dump_instr(KERN_ERR, regs);
++		show_pte(current->mm, addr);
++	}
++#endif
++
++	info.si_signo = SIGILL;
++	info.si_errno = 0;
++	info.si_code  = ILL_ILLOPC;
++	info.si_addr  = (void __user *)addr;
++
++	arm_notify_die("unknown data abort code", regs, &info, instr, 0);
++}
++
++void __attribute__((noreturn)) __bug(const char *file, int line)
++{
++	printk(KERN_CRIT"kernel BUG at %s:%d!\n", file, line);
++	*(int *)0 = 0;
++
++	/* Avoid "noreturn function does return" */
++	for (;;);
++}
++EXPORT_SYMBOL(__bug);
++
++void __readwrite_bug(const char *fn)
++{
++	printk("%s called, but not implemented\n", fn);
++	BUG();
++}
++EXPORT_SYMBOL(__readwrite_bug);
++
++void __pte_error(const char *file, int line, unsigned long val)
++{
++	printk("%s:%d: bad pte %08lx.\n", file, line, val);
++}
++
++void __pmd_error(const char *file, int line, unsigned long val)
++{
++	printk("%s:%d: bad pmd %08lx.\n", file, line, val);
++}
++
++void __pgd_error(const char *file, int line, unsigned long val)
++{
++	printk("%s:%d: bad pgd %08lx.\n", file, line, val);
++}
++
++asmlinkage void __div0(void)
++{
++	printk("Division by zero in kernel.\n");
++	dump_stack();
++}
++EXPORT_SYMBOL(__div0);
++
++void abort(void)
++{
++	BUG();
++
++	/* if that doesn't kill us, halt */
++	panic("Oops failed to kill thread");
++}
++EXPORT_SYMBOL(abort);
++
++void __init trap_init(void)
++{
++	return;
++}
++
++void __init early_trap_init(void)
++{
++	unsigned long vectors = CONFIG_VECTORS_BASE;
++	extern char __stubs_start[], __stubs_end[];
++	extern char __vectors_start[], __vectors_end[];
++	extern char __kuser_helper_start[], __kuser_helper_end[];
++	int kuser_sz = __kuser_helper_end - __kuser_helper_start;
++
++	/*
++	 * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
++	 * into the vector page, mapped at 0xffff0000, and ensure these
++	 * are visible to the instruction stream.
++	 */
++	memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
++	memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
++	memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
++
++	/*
++	 * Copy signal return handlers into the vector page, and
++	 * set sigreturn to be a pointer to these.
++	 */
++	memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
++	       sizeof(sigreturn_codes));
++	memcpy((void *)KERN_RESTART_CODE, syscall_restart_code,
++	       sizeof(syscall_restart_code));
++
++	flush_icache_range(vectors, vectors + PAGE_SIZE);
++	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
++}
+diff -rupN linux-2.6.35.11/arch/arm/kernel/vmlinux.lds.S linux-2.6.35.11-ts7500/arch/arm/kernel/vmlinux.lds.S
+--- linux-2.6.35.11/arch/arm/kernel/vmlinux.lds.S	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/vmlinux.lds.S	2011-03-14 11:18:24.000000000 -0400
+@@ -84,6 +84,12 @@ SECTIONS
+ 
+ 	.text : {			/* Real text segment		*/
+ 		_text = .;		/* Text and read-only data	*/
++#ifdef CONFIG_CPU_ISPAD_ENABLE
++			. = ALIGN(1024);
++			__ispad_begin = .;
++			*(.ispad)
++			__ispad_end = .;
++#endif      
+ 			__exception_text_start = .;
+ 			*(.exception.text)
+ 			__exception_text_end = .;
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/debug-macro.S linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/debug-macro.S
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/debug-macro.S	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,54 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++//#include <linux/config.h>
++#include <linux/linkage.h>
++#include <mach/hardware.h>
++
++		.macro	addruart,rx,tmp
++		mrc	p15, 0, \rx, c1, c0
++		tst	\rx, #1				@ MMU enabled ?
++		moveq	\rx, #(SYSPA_UART0_BASE_ADDR)	@ physical base address of UART0
++		movne	\rx, #(SYSVA_UART0_BASE_ADDR & 0xFF000000) @ virtual base address of UART0
++		orrne	\rx, \rx, #(SYSVA_UART0_BASE_ADDR & 0x00FF0000)
++		orrne	\rx, \rx, #(SYSVA_UART0_BASE_ADDR & 0x0000FF00)
++		orrne	\rx, \rx, #(SYSVA_UART0_BASE_ADDR & 0x000000FF)
++		.endm
++
++		.macro	senduart,rd,rx
++		strb	\rd, [\rx, #0x00]
++		.endm
++
++		.macro	waituart,rd,rx
++		mov	\rd, #0xf000
++1001:		subs	\rd, \rd, #1
++		bne	1001b	
++		.endm
++
++		.macro	busyuart,rd,rx
++		nop
++		mov	\rd, #0xf000
++1010:		subs	\rd, \rd, #1
++		bne	1010b
++		.endm
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/dma.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/dma.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/dma.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/dma.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,27 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_DMA_H__
++#define __ASM_ARCH_DMA_H__
++
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/entry-macro.S linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/entry-macro.S
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/entry-macro.S	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,79 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++//#include <mach/star_intc.h>
++#include <mach/star_intc.h>
++
++	.macro	disable_fiq
++	.endm
++
++	.macro	get_irqnr_preamble, base, tmp
++	.endm
++
++	.macro	arch_ret_to_user, tmp1, tmp2
++	.endm
++
++
++#ifdef CONFIG_VIC_INTERRUPT
++	.macro	get_fiqnr_and_base, irqnr, irqstat, base, tmp
++	ldr	\base, =(SYSVA_VIC_BASE_ADDR + 0x140)
++	ldr	\irqnr, [\base]
++	.endm
++
++	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
++	ldr	\base, =(SYSVA_VIC_BASE_ADDR + 0x140)
++	ldr	\irqnr, [\base]
++	.endm
++#else
++	.macro	get_fiqnr_and_base, irqnr, irqstat, base, tmp
++	ldr	\base, =(SYSVA_VIC_BASE_ADDR + 0x20)
++	ldr	\irqstat, [\base]
++	mov	\irqnr, #0
++9001:
++	tst	\irqstat, #1
++	bne	9002f
++	add	\irqnr, \irqnr, #1
++	mov	\irqstat, \irqstat, lsr #1
++	cmp	\irqnr, #32
++	bcc	9001b
++9002:
++	.endm
++
++	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
++	ldr	\base, =(SYSVA_VIC_BASE_ADDR + 0x1C)
++	ldr	\irqstat, [\base]
++	mov	\irqnr, #0
++9003:
++	tst	\irqstat, #1
++	bne	9004f
++	add	\irqnr, \irqnr, #1
++	mov	\irqstat, \irqstat, lsr #1
++	cmp	\irqnr, #32
++	bcc	9003b
++9004:
++	.endm
++#endif
++
++	.macro	irq_prio_table
++	.endm
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/hardware.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/hardware.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/hardware.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,71 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_HARDWARE_H__
++#define __ASM_ARCH_HARDWARE_H__
++
++//#include <linux/config.h>
++#include <mach/param.h>
++
++#include <mach/star_sys_memory_map.h>
++#include <mach/star_intc.h>
++#include <mach/star_timer.h>
++#include <mach/star_uart.h>
++#include <mach/star_gpio.h>
++#include <mach/star_pci_bridge.h>
++#include <mach/star_misc.h>
++#include <mach/star_powermgt.h>
++#include <mach/star_rtc.h>
++#include <mach/star_wdtimer.h>
++#include <mach/star_smc.h>
++#include <mach/star_nic.h>
++#include <mach/star_ide.h>
++
++#if 1 // on ASIC
++#define SYS_CLK			(87500000) // 87.5MHz
++#define UART_CLK		(24000000) // 24MHz
++#define AHB_CLK			(SYS_CLK)
++#define APB_CLK			(AHB_CLK >> 1)
++#define TIMER_COUNTER		(APB_CLK / HZ)
++#else // on FPGA
++#define SYS_CLK			(13000000) // 13MHz
++#define UART_CLK		(13000000) // 13Mhz
++#define AHB_CLK			(SYS_CLK)
++#define APB_CLK			(AHB_CLK)
++#define TIMER_COUNTER		(APB_CLK / HZ)
++#endif
++
++#define DEBUG_CONSOLE		(0)
++
++#define FLASH_BASE_ADDR		SYSPA_FLASH_SRAM_BANK0_BASE_ADDR
++#define FLASH_SIZE		0x800000
++
++#define PCIBIOS_MIN_IO		0x00000000
++#define PCIBIOS_MIN_MEM		0x00000000
++#if 1
++#define pcibios_assign_all_busses()	0
++#else
++#define pcibios_assign_all_busses()	1
++#endif
++
++#endif /* __ASM_ARCH_HARDWARE_H__ */
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/io.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/io.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/io.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,35 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_IO_H__
++#define __ASM_ARCH_IO_H__
++
++//#include <asm/hardware.h>
++
++#define IO_SPACE_LIMIT		0xffffffff
++
++#define __io(p)			((void __iomem *)(p))
++#define __mem_pci(a)		(a)
++#define __mem_isa(a)		(a)
++
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/irqs.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/irqs.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/irqs.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,36 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_IRQS_H__
++#define __ASM_ARCH_IRQS_H__
++
++//#include <mach/star_intc.h>
++#include <mach/star_intc.h>
++
++#define NR_IRQS (32)
++
++#ifdef CONFIG_VIC_INTERRUPT 
++#define irq_finish(irq) do { INTC_IRQ_VECTOR_ADDRESS_REG = 0; } while (0)
++#endif
++
++#endif /* __ASM_ARCH_IRQS_H__ */
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/memory.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/memory.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/memory.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,82 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_MEMORY_H
++#define __ASM_ARCH_MEMORY_H
++
++#if 0
++#define TASK_SIZE		(0xC0000000UL)	
++#define TASK_SIZE_26		(0x04000000UL)
++#define TASK_UNMAPPED_BASE	(TASK_SIZE / 3)
++#endif
++
++#define CONFIG_SYSTEM_DRAM_BASE	0x00000000
++#if defined(CONFIG_STR8100_DRAM_64M)
++#define CONFIG_SYSTEM_DRAM_SIZE 64
++#elif defined(CONFIG_STR8100_DRAM_32M)
++#define CONFIG_SYSTEM_DRAM_SIZE 32
++#elif defined(CONFIG_STR8100_DRAM_16M)
++#define CONFIG_SYSTEM_DRAM_SIZE 16
++#endif
++#define MEM_SIZE		(CONFIG_SYSTEM_DRAM_SIZE)
++#define END_MEM			(CONFIG_SYSTEM_DRAM_BASE + CONFIG_SYSTEM_DRAM_SIZE)
++#define DMA_SIZE		0xffffffff
++#define PHYS_OFFSET		(CONFIG_SYSTEM_DRAM_BASE) // physical start address of memory
++#if 0
++#define PAGE_OFFSET 		(0xC0000000UL)
++#endif
++
++/*
++#define __virt_to_bus(x)	((x) - PAGE_OFFSET)
++#define __bus_to_virt(x)	((x) + PAGE_OFFSET)
++*/
++#if 0
++#define __virt_to_phys__is_a_macro
++#define __virt_to_phys(vpage)	((vpage) - PAGE_OFFSET)
++
++#define __phys_to_virt__is_a_macro
++#define __phys_to_virt(ppage)	((ppage) + PAGE_OFFSET)
++
++#define __virt_to_bus__is_a_macro
++#define __virt_to_bus(x)	((x) - PAGE_OFFSET)
++
++#define __bus_to_virt__is_a_macro
++#define __bus_to_virt(x)	((x) + PAGE_OFFSET)
++#endif
++
++/*
++#define __virt_to_bus(x) __virt_to_phys(x)
++#define __bus_to_virt(x) __phys_to_virt(x)
++
++#define __pfn_to_bus(x) __pfn_to_phys(x)
++#define __bus_to_pfn(x) __phys_to_pfn(x)
++*/
++
++/*
++#define __pfn_to_bus(p)         __phys_to_bus(__pfn_to_phys(p))
++#define __bus_to_pfn(b)         __phys_to_pfn(__bus_to_phys(b))
++*/
++
++
++
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/param.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/param.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/param.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/param.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,32 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_PARAM_H__
++#define __ASM_ARCH_PARAM_H__
++
++// For timer, there will be HZ ticks per second
++/* scott.patch
++#define HZ	100
++*/
++
++#endif /* __ARCH_ASM_PARAM_H__ */
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_demo_dma.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_demo_dma.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_demo_dma.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_demo_dma.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,189 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __DEMO_DMA_H__
++#define __DEMO_DMA_H__
++#include <linux/types.h>	/* size_t */
++#include <linux/interrupt.h>
++#include <linux/module.h>
++
++#include <mach/star_dmac.h>
++
++/*
++ * defines for each channel
++ */
++#define DMAC_CH_DISABLE                0
++#define DMAC_CH_ENABLE                 1
++
++#define DMAC_CH_DST_SEL_M0             0
++#define DMAC_CH_DST_SEL_M1             1
++
++#define DMAC_CH_SRC_SEL_M0             0
++#define DMAC_CH_SRC_SEL_M1             1
++
++#define DMAC_CH_DSTAD_CTL_INC          0
++#define DMAC_CH_DSTAD_CTL_DEC          1
++#define DMAC_CH_DSTAD_CTL_FIX          2
++
++#define DMAC_CH_SRCAD_CTL_INC          0
++#define DMAC_CH_SRCAD_CTL_DEC          1
++#define DMAC_CH_SRCAD_CTL_FIX          2
++
++#define DMAC_CH_MODE_HW_HANDSHAKE      1
++
++#define DMAC_CH_SRC_WIDTH_8_BITS       0
++#define DMAC_CH_SRC_WIDTH_16_BITS      1
++#define DMAC_CH_SRC_WIDTH_32_BITS      2
++
++#define DMAC_CH_DST_WIDTH_8_BITS       0
++#define DMAC_CH_DST_WIDTH_16_BITS      1
++#define DMAC_CH_DST_WIDTH_32_BITS      2
++
++#define DMAC_CH_ABT_TRANSFER           1
++
++#define DMAC_CH_PROT1_PRIVILEGED_MODE  1
++#define DMAC_CH_PROT1_USER_MODE        0
++
++#define DMAC_CH_PROT2_BUFFERABLE       1
++#define DMAC_CH_PROT2_NON_BUFFERABLE   0
++
++#define DMAC_CH_PROT3_CACHEABLE        1
++#define DMAC_CH_PROT3_NON_CACHEABLE    0
++
++#define DMAC_CH_PRI_LEVEL_0            0
++#define DMAC_CH_PRI_LEVEL_1            1
++#define DMAC_CH_PRI_LEVEL_2            2
++#define DMAC_CH_PRI_LEVEL_3            3
++
++#define DMAC_CH_TC_MASK_DISABLE        0
++#define DMAC_CH_TC_MASK_ENABLE         1
++
++#define DMAC_MAX_CHANNEL_NUM           (8)
++
++
++#define DMAC_CH0_ID                    (1 << 0)
++#define DMAC_CH1_ID                    (1 << 1)
++#define DMAC_CH2_ID                    (1 << 2)
++#define DMAC_CH3_ID                    (1 << 3)
++#define DMAC_CH4_ID                    (1 << 4)
++#define DMAC_CH5_ID                    (1 << 5)
++#define DMAC_CH6_ID                    (1 << 6)
++#define DMAC_CH7_ID                    (1 << 7)
++#define DMAC_CH_ID(idx)                (1 << idx) 
++
++#define DMAC_LITTLE_ENDIAN             (0)
++#define DMAC_BIG_ENDIAN                (1)
++
++/* 
++ * DMAC LLP Descriptor
++ */
++typedef struct _DMAC_LLP_CONTROL_    DMAC_LLP_CONTROL_T;
++
++struct _DMAC_LLP_CONTROL_
++{
++//#if (ENDIAN_MODE == LITTLE_ENDIAN)
++#if 1
++    unsigned int    tot_size              : 12;//b11-0
++    unsigned int    reserved_1            : 4; //b15-12    
++    unsigned int    dst_sel               : 1; //b16
++    unsigned int    src_sel               : 1; //b17    
++    unsigned int    dstad_ctl             : 2; //b19-18        
++    unsigned int    srcad_ctl             : 2; //b21-20        
++    unsigned int    dst_width             : 3; //b24-22
++    unsigned int    src_width             : 3; //b27-25
++    unsigned int    tc_status_mask        : 1; //b28
++    unsigned int    reserved_0            : 3; //b31-29
++
++#else
++
++
++    unsigned int    reserved_0            : 3; //b31-29
++    unsigned int    tc_status_mask        : 1; //b28
++    unsigned int    src_width             : 3; //b27-25
++    unsigned int    dst_width             : 3; //b24-22
++    unsigned int    srcad_ctl             : 2; //b21-20
++    unsigned int    dstad_ctl             : 2; //b19-18    
++    unsigned int    src_sel               : 1; //b17
++    unsigned int    dst_sel               : 1; //b16
++    unsigned int    reserved_1            : 4; //b15-12
++    unsigned int    tot_size              : 12;//b11-0
++
++
++#endif
++}; 
++
++
++/* 
++ * DMAC LLP Descriptor object
++ */
++typedef struct _DMAC_LLP_    DMAC_LLP_T;
++struct _DMAC_LLP_
++{
++    unsigned int    SrcAddr;
++    
++    unsigned int    DstAddr;
++    
++    DMAC_LLP_T     *LLP;
++
++    DMAC_LLP_CONTROL_T    Ctrl_TotSize;    
++};
++
++typedef struct _DMAC_HARDWARE_HANDSHAKE_OBJ_    DMAC_HARDWARE_HANDSHAKE_OBJ_T;
++struct _DMAC_HARDWARE_HANDSHAKE_OBJ_
++{
++    unsigned int    src_addr;                     //Src address
++    unsigned int    dst_addr;                     //Dst address
++    unsigned int    src_master;                   //0:AHB0, 1:AHB1
++    unsigned int    dst_master;                   //0:AHB0, 1:AHB1
++    unsigned int    dstad_ctl;                    //0:Incr, 1:Decr, 2:Fix
++    unsigned int    srcad_ctl;                    //0:Incr, 1:Decr, 2:Fix
++    unsigned int    src_width;                    //0:8bits, 1:16bits, 2:32bits
++    unsigned int    dst_width;                    //0:8bits, 1:16bits, 2:32bits
++    unsigned int    transfer_bytes;               //Byte Count to be transferred
++    unsigned int    channel_id;                   //0~7 for Channel0-7 selection
++    unsigned int    channel_num;                   //0~7
++    unsigned int    target_select;                //target ID
++    unsigned int    src_burst_size;               //number of transfer 
++    unsigned int    llp_addr;                     //LLP address
++
++    void * private_data;
++    DMAC_LLP_T* llp_head;
++}; 
++
++
++extern void Hal_Dmac_Configure_DMA_Handshake(DMAC_HARDWARE_HANDSHAKE_OBJ_T *dmac_obj);
++extern irqreturn_t str8100_dma_err_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs);
++//extern int str8100_i2s_init(int sampling_rate);
++extern int str8100_i2s_init(int sampling_rate,u32 i2s_sdata_width, u32 i2s_mode,
++			u32 i2s_tranfer_timing_ctrl, u32 i2s_sclk_mode);
++extern u32 Hal_Dmac_Get_Channel_Transfer_Unit_Number(u32 byte_size, u32 src_width);
++
++extern u32 I2s_Gpio_SSP_Initialise(void);
++extern void I2s_Gpio_SSP_Write(u16);
++extern void I2s_Gpio_SSP_Switch_To_Record_Data(void);
++extern void I2s_Gpio_SSP_Switcg_To_Playback_Data(void);
++
++
++#endif //#ifndef __DEMO_DMA_H__
++
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_dmac.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_dmac.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_dmac.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_dmac.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,409 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_DMAC_H_
++#define	_STAR_DMAC_H_
++
++
++#include "star_sys_memory_map.h"
++
++
++#if defined(__UBOOT__)
++#define	DMAC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_GDMAC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	DMAC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_GDMAC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	DMAC_INT_STATUS_REG			DMAC_MEM_MAP_VALUE(0x000)
++
++#define	DMAC_INT_TC_STATUS_REG			DMAC_MEM_MAP_VALUE(0x004)
++#define	DMAC_INT_TC_STATUS_CLR_REG		DMAC_MEM_MAP_VALUE(0x008)
++
++#define	DMAC_INT_ERR_STATUS_REG			DMAC_MEM_MAP_VALUE(0x00C)
++#define	DMAC_INT_ERR_STATUS_CLR_REG		DMAC_MEM_MAP_VALUE(0x010)
++
++#define	DMAC_TC_STATUS_REG			DMAC_MEM_MAP_VALUE(0x014)
++#define	DMAC_ERR_STATUS_REG			DMAC_MEM_MAP_VALUE(0x018)
++
++#define	DMAC_CH_ENABLE_STATUS_REG		DMAC_MEM_MAP_VALUE(0x01C)
++#define	DMAC_CH_BUSY_STATUS_REG			DMAC_MEM_MAP_VALUE(0x020)
++
++#define	DMAC_CSR_REG				DMAC_MEM_MAP_VALUE(0x024)
++#define	DMAC_SYNC_REG				DMAC_MEM_MAP_VALUE(0x028)
++
++#define	DMAC_CH0_CSR_REG			DMAC_MEM_MAP_VALUE(0x100)
++#define	DMAC_CH0_CFG_REG			DMAC_MEM_MAP_VALUE(0x104)
++#define	DMAC_CH0_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x108)
++#define	DMAC_CH0_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x10C)
++#define	DMAC_CH0_LLP_REG			DMAC_MEM_MAP_VALUE(0x110)
++#define	DMAC_CH0_SIZE_REG			DMAC_MEM_MAP_VALUE(0x114)
++
++#define	DMAC_CH1_CSR_REG			DMAC_MEM_MAP_VALUE(0x120)
++#define	DMAC_CH1_CFG_REG			DMAC_MEM_MAP_VALUE(0x124)
++#define	DMAC_CH1_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x128)
++#define	DMAC_CH1_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x12C)
++#define	DMAC_CH1_LLP_REG			DMAC_MEM_MAP_VALUE(0x130)
++#define	DMAC_CH1_SIZE_REG			DMAC_MEM_MAP_VALUE(0x134)
++
++#define	DMAC_CH2_CSR_REG			DMAC_MEM_MAP_VALUE(0x140)
++#define	DMAC_CH2_CFG_REG			DMAC_MEM_MAP_VALUE(0x144)
++#define	DMAC_CH2_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x148)
++#define	DMAC_CH2_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x14C)
++#define	DMAC_CH2_LLP_REG			DMAC_MEM_MAP_VALUE(0x150)
++#define	DMAC_CH2_SIZE_REG			DMAC_MEM_MAP_VALUE(0x154)
++
++#define	DMAC_CH3_CSR_REG			DMAC_MEM_MAP_VALUE(0x160)
++#define	DMAC_CH3_CFG_REG			DMAC_MEM_MAP_VALUE(0x164)
++#define	DMAC_CH3_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x168)
++#define	DMAC_CH3_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x16C)
++#define	DMAC_CH3_LLP_REG			DMAC_MEM_MAP_VALUE(0x170)
++#define	DMAC_CH3_SIZE_REG			DMAC_MEM_MAP_VALUE(0x174)
++
++#define	DMAC_CH4_CSR_REG			DMAC_MEM_MAP_VALUE(0x180)
++#define	DMAC_CH4_CFG_REG			DMAC_MEM_MAP_VALUE(0x184)
++#define	DMAC_CH4_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x188)
++#define	DMAC_CH4_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x18C)
++#define	DMAC_CH4_LLP_REG			DMAC_MEM_MAP_VALUE(0x190)
++#define	DMAC_CH4_SIZE_REG			DMAC_MEM_MAP_VALUE(0x194)
++
++#define	DMAC_CH5_CSR_REG			DMAC_MEM_MAP_VALUE(0x1A0)
++#define	DMAC_CH5_CFG_REG			DMAC_MEM_MAP_VALUE(0x1A4)
++#define	DMAC_CH5_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1A8)
++#define	DMAC_CH5_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1AC)
++#define	DMAC_CH5_LLP_REG			DMAC_MEM_MAP_VALUE(0x1B0)
++#define	DMAC_CH5_SIZE_REG			DMAC_MEM_MAP_VALUE(0x1B4)
++
++#define	DMAC_CH6_CSR_REG			DMAC_MEM_MAP_VALUE(0x1C0)
++#define	DMAC_CH6_CFG_REG			DMAC_MEM_MAP_VALUE(0x1C4)
++#define	DMAC_CH6_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1C8)
++#define	DMAC_CH6_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1CC)
++#define	DMAC_CH6_LLP_REG			DMAC_MEM_MAP_VALUE(0x1D0)
++#define	DMAC_CH6_SIZE_REG			DMAC_MEM_MAP_VALUE(0x1D4)
++
++#define	DMAC_CH7_CSR_REG			DMAC_MEM_MAP_VALUE(0x1E0)
++#define	DMAC_CH7_CFG_REG			DMAC_MEM_MAP_VALUE(0x1E4)
++#define	DMAC_CH7_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1E8)
++#define	DMAC_CH7_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1EC)
++#define	DMAC_CH7_LLP_REG			DMAC_MEM_MAP_VALUE(0x1F0)
++#define	DMAC_CH7_SIZE_REG			DMAC_MEM_MAP_VALUE(0x1F4)
++
++
++#define DMAC_CH0_INT_BIT_INDEX			0
++#define DMAC_CH1_INT_BIT_INDEX			1
++#define DMAC_CH2_INT_BIT_INDEX			2
++#define DMAC_CH3_INT_BIT_INDEX			3
++#define DMAC_CH4_INT_BIT_INDEX			4
++#define DMAC_CH5_INT_BIT_INDEX			5
++#define DMAC_CH6_INT_BIT_INDEX			6
++#define DMAC_CH7_INT_BIT_INDEX			7
++
++#define DMAC_CH0_INT_TC_BIT_INDEX		0
++#define DMAC_CH1_INT_TC_BIT_INDEX		1
++#define DMAC_CH2_INT_TC_BIT_INDEX		2
++#define DMAC_CH3_INT_TC_BIT_INDEX		3
++#define DMAC_CH4_INT_TC_BIT_INDEX		4
++#define DMAC_CH5_INT_TC_BIT_INDEX		5
++#define DMAC_CH6_INT_TC_BIT_INDEX		6
++#define DMAC_CH7_INT_TC_BIT_INDEX		7
++
++#define DMAC_CH0_INT_TC_CLR_BIT_INDEX		0
++#define DMAC_CH1_INT_TC_CLR_BIT_INDEX		1
++#define DMAC_CH2_INT_TC_CLR_BIT_INDEX		2
++#define DMAC_CH3_INT_TC_CLR_BIT_INDEX		3
++#define DMAC_CH4_INT_TC_CLR_BIT_INDEX		4
++#define DMAC_CH5_INT_TC_CLR_BIT_INDEX		5
++#define DMAC_CH6_INT_TC_CLR_BIT_INDEX		6
++#define DMAC_CH7_INT_TC_CLR_BIT_INDEX		7
++
++#define DMAC_CH0_INT_ERR_BIT_INDEX		0
++#define DMAC_CH1_INT_ERR_BIT_INDEX		1
++#define DMAC_CH2_INT_ERR_BIT_INDEX		2
++#define DMAC_CH3_INT_ERR_BIT_INDEX		3
++#define DMAC_CH4_INT_ERR_BIT_INDEX		4
++#define DMAC_CH5_INT_ERR_BIT_INDEX		5
++#define DMAC_CH6_INT_ERR_BIT_INDEX		6
++#define DMAC_CH7_INT_ERR_BIT_INDEX		7
++
++#define DMAC_CH0_INT_ERR_CLR_BIT_INDEX		0
++#define DMAC_CH1_INT_ERR_CLR_BIT_INDEX		1
++#define DMAC_CH2_INT_ERR_CLR_BIT_INDEX		2
++#define DMAC_CH3_INT_ERR_CLR_BIT_INDEX		3
++#define DMAC_CH4_INT_ERR_CLR_BIT_INDEX		4
++#define DMAC_CH5_INT_ERR_CLR_BIT_INDEX		5
++#define DMAC_CH6_INT_ERR_CLR_BIT_INDEX		6
++#define DMAC_CH7_INT_ERR_CLR_BIT_INDEX		7
++
++#define DMAC_CH0_TC_STATUS_BIT_INDEX		0
++#define DMAC_CH1_TC_STATUS_BIT_INDEX		1
++#define DMAC_CH2_TC_STATUS_BIT_INDEX		2
++#define DMAC_CH3_TC_STATUS_BIT_INDEX		3
++#define DMAC_CH4_TC_STATUS_BIT_INDEX		4
++#define DMAC_CH5_TC_STATUS_BIT_INDEX		5
++#define DMAC_CH6_TC_STATUS_BIT_INDEX		6
++#define DMAC_CH7_TC_STATUS_BIT_INDEX		7
++
++#define DMAC_CH0_ERR_STATUS_BIT_INDEX		0
++#define DMAC_CH1_ERR_STATUS_BIT_INDEX		1
++#define DMAC_CH2_ERR_STATUS_BIT_INDEX		2
++#define DMAC_CH3_ERR_STATUS_BIT_INDEX		3
++#define DMAC_CH4_ERR_STATUS_BIT_INDEX		4
++#define DMAC_CH5_ERR_STATUS_BIT_INDEX		5
++#define DMAC_CH6_ERR_STATUS_BIT_INDEX		6
++#define DMAC_CH7_ERR_STATUS_BIT_INDEX		7
++
++#define DMAC_CH0_ENABLE_STATUS_BIT_INDEX	0
++#define DMAC_CH1_ENABLE_STATUS_BIT_INDEX	1
++#define DMAC_CH2_ENABLE_STATUS_BIT_INDEX	2
++#define DMAC_CH3_ENABLE_STATUS_BIT_INDEX	3
++#define DMAC_CH4_ENABLE_STATUS_BIT_INDEX	4
++#define DMAC_CH5_ENABLE_STATUS_BIT_INDEX	5
++#define DMAC_CH6_ENABLE_STATUS_BIT_INDEX	6
++#define DMAC_CH7_ENABLE_STATUS_BIT_INDEX	7
++
++#define DMAC_CH0_BUSY_STATUS_BIT_INDEX		0
++#define DMAC_CH1_BUSY_STATUS_BIT_INDEX		1
++#define DMAC_CH2_BUSY_STATUS_BIT_INDEX		2
++#define DMAC_CH3_BUSY_STATUS_BIT_INDEX		3
++#define DMAC_CH4_BUSY_STATUS_BIT_INDEX		4
++#define DMAC_CH5_BUSY_STATUS_BIT_INDEX		5
++#define DMAC_CH6_BUSY_STATUS_BIT_INDEX		6
++#define DMAC_CH7_BUSY_STATUS_BIT_INDEX		7
++
++#define DMAC_ENABLE_BIT_INDEX			0
++#define DMAC_MASTER0_ENDIAN_BIT_INDEX		1
++#define DMAC_MASTER1_ENDIAN_BIT_INDEX		2
++
++#define DMAC_CH0_SYNC_ENABLE_BIT_INDEX		0
++#define DMAC_CH1_SYNC_ENABLE_BIT_INDEX		1
++#define DMAC_CH2_SYNC_ENABLE_BIT_INDEX		2
++#define DMAC_CH3_SYNC_ENABLE_BIT_INDEX		3
++#define DMAC_CH4_SYNC_ENABLE_BIT_INDEX		4
++#define DMAC_CH5_SYNC_ENABLE_BIT_INDEX		5
++#define DMAC_CH6_SYNC_ENABLE_BIT_INDEX		6
++#define DMAC_CH7_SYNC_ENABLE_BIT_INDEX		7
++
++#define DMAC_CH_INT_TC_MASK_BIT_INDEX		0
++#define DMAC_CH_INT_ERR_MASK_BIT_INDEX		1
++#define DMAC_CH_INT_ABT_MASK_BIT_INDEX		2
++#define DMAC_CH_BUSY_BIT_INDEX			8
++
++#define DMAC_CH_ENABLE_BIT_INDEX		0
++#define DMAC_CH_DST_SEL_BIT_INDEX		1
++#define DMAC_CH_SRC_SEL_BIT_INDEX		2
++#define DMAC_CH_DST_ADDR_CTL_BIT_INDEX		3
++#define DMAC_CH_SRC_ADDR_CTL_BIT_INDEX		5
++#define DMAC_CH_MODE_BIT_INDEX			7
++#define DMAC_CH_DST_WIDTH_BIT_INDEX		8
++#define DMAC_CH_SRC_WIDTH_BIT_INDEX		11
++#define DMAC_CH_ABT_BIT_INDEX			15
++#define DMAC_CH_SRC_BURST_SIZE_BIT_INDEX	16
++#define DMAC_CH_PROTECT_MODE_BIT_INDEX		19
++#define DMAC_CH_PROTECT_BUFFERABLE_BIT_INDEX	20
++#define DMAC_CH_PROTECT_CACHEABLE_BIT_INDEX	21
++#define DMAC_CH_PRIORITY_BIT_INDEX		22
++#define DMAC_CH_HHST_SEL_BIT_INDEX		25
++
++#define DMAC_CH_DST_ADDR_CTL_MASK		0x3
++#define DMAC_CH_DST_ADDR_CTL_INC		0x0
++#define DMAC_CH_DST_ADDR_CTL_DEC		0x1
++#define DMAC_CH_DST_ADDR_CTL_FIXED		0x2
++
++#define DMAC_CH_SRC_ADDR_CTL_MASK		0x3
++#define DMAC_CH_SRC_ADDR_CTL_INC		0x0
++#define DMAC_CH_SRC_ADDR_CTL_DEC		0x1
++#define DMAC_CH_SRC_ADDR_CTL_FIXED		0x2
++
++#define DMAC_CH_MODE_NORMAL			0x0
++#define DMAC_CH_MODE_HANDSHAKE			0x1
++
++#define DMAC_CH_DST_WIDTH_MASK			0x3
++#define DMAC_CH_DST_WIDTH_8BIT			0x0
++#define DMAC_CH_DST_WIDTH_16BIT			0x1
++#define DMAC_CH_DST_WIDTH_32BIT			0x2
++
++#define DMAC_CH_SRC_WIDTH_MASK			0x3
++#define DMAC_CH_SRC_WIDTH_8BIT			0x0
++#define DMAC_CH_SRC_WIDTH_16BIT			0x1
++#define DMAC_CH_SRC_WIDTH_32BIT			0x2
++
++#define DMAC_CH_SRC_BURST_SIZE_MASK		0x8
++#define DMAC_CH_SRC_BURST_SIZE_1		0x0
++#define DMAC_CH_SRC_BURST_SIZE_4		0x1
++#define DMAC_CH_SRC_BURST_SIZE_8		0x2
++#define DMAC_CH_SRC_BURST_SIZE_16		0x3
++#define DMAC_CH_SRC_BURST_SIZE_32		0x4
++#define DMAC_CH_SRC_BURST_SIZE_64		0x5
++#define DMAC_CH_SRC_BURST_SIZE_128		0x6
++#define DMAC_CH_SRC_BURST_SIZE_256		0x7
++
++#define DMAC_CH_PRIORITY_MASK			0x4
++#define DMAC_CH_PRIORITY_0			0x0	/* lowest priority */
++#define DMAC_CH_PRIORITY_1			0x1
++#define DMAC_CH_PRIORITY_2			0x2
++#define DMAC_CH_PRIORITY_3			0x3	/* highest priority */
++
++
++#define	DMAC_CH_CSR_REG(idx)			DMAC_MEM_MAP_VALUE(0x100+0x20*(idx))
++#define	DMAC_CH_CFG_REG(idx)			DMAC_MEM_MAP_VALUE(0x104+0x20*(idx))
++#define	DMAC_CH_SRC_ADDR_REG(idx)		DMAC_MEM_MAP_VALUE(0x108+0x20*(idx))
++#define	DMAC_CH_DST_ADDR_REG(idx)		DMAC_MEM_MAP_VALUE(0x10C+0x20*(idx))
++#define	DMAC_CH_LLP_REG(idx)			DMAC_MEM_MAP_VALUE(0x110+0x20*(idx))
++#define	DMAC_CH_SIZE_REG(idx)			DMAC_MEM_MAP_VALUE(0x114+0x20*(idx))
++
++
++#define	HAL_DMAC_ENABLE_CHANNEL(idx)		((DMAC_CH_CSR_REG(idx)) |= (0x1))
++
++#define	HAL_DMAC_DISABLE_CHANNEL(idx)		((DMAC_CH_CSR_REG(idx)) &= ~(0x1))
++
++#define	HAL_GET_DMAC_CHANNEL_LLP_COUNTER(ch)	((DMAC_CH_CFG_REG(ch) >> 16) & 0xF)
++
++
++/*DMAC HW Hand-shake target ID*/
++#define	DMAC_HW_HAND_SHAKE_PCM_TX0_ID		0x0
++#define	DMAC_HW_HAND_SHAKE_PCM_RX0_ID		0x1
++
++#define	DMAC_HW_HAND_SHAKE_SPI_TX_ID		0x2
++#define	DMAC_HW_HAND_SHAKE_SPI_RX_ID		0x3
++
++#define	DMAC_HW_HAND_SHAKE_I2S_TX_LEFT_ID	0x4
++#define	DMAC_HW_HAND_SHAKE_I2S_TX_RIGHT_ID	0x5
++
++#define	DMAC_HW_HAND_SHAKE_UART0_TX_ID		0x6
++#define	DMAC_HW_HAND_SHAKE_UART0_RX_ID		0x7
++
++#define	DMAC_HW_HAND_SHAKE_UART1_TX_ID		0x8
++#define	DMAC_HW_HAND_SHAKE_UART1_RX_ID		0x9
++
++#define	DMAC_HW_HAND_SHAKE_USBDEV_ID		0xA
++
++#define	DMAC_HW_HAND_SHAKE_I2S_RX_LEFT_ID	0xB
++#define	DMAC_HW_HAND_SHAKE_I2S_RX_RIGHT_ID	0xC
++
++#define	DMAC_HW_HAND_SHAKE_PCM_TX1_ID		0xD
++#define	DMAC_HW_HAND_SHAKE_PCM_RX1_ID		0xE
++
++
++#define MAX_DMA_VEC				32
++
++#define DMAC_DST_SEL_MASTER0			0
++#define DMAC_DST_SEL_MASTER1			1
++#define DMAC_SRC_SEL_MASTER0			0
++#define DMAC_SRC_SEL_MASTER1			1
++
++#define DMAC_RESPONSE_OK			0
++#define DMAC_RESPONSE_ERR			-1
++
++struct dma_xfer;
++typedef struct dma_xfer dma_xfer_t;
++typedef void (*dma_end_io_t)(dma_xfer_t *dma_xfer, int err);
++typedef struct
++{
++	u32	src_addr;	// virtual addr
++	u32	dst_addr;	// virtual addr
++	u32	size;		// bytes
++	u8	dst_sel;
++	u8	src_sel;
++	u8	dst_addr_ctl;
++	u8	src_addr_ctl;
++	u8	dst_width;
++	u8	src_width;
++} dma_vec_t;
++
++struct dma_xfer
++{
++	u8		nr_vec;
++	dma_vec_t	vec[MAX_DMA_VEC];
++	dma_end_io_t	dma_end_io;
++	void		*private;
++};
++
++/*
++ * DMAC	LLP Descriptor
++ */
++typedef struct
++{
++	u32	src_addr;			// physical addr
++	u32	dst_addr;			// physical addr
++	u32	llp;
++	u32	tot_size	: 12;
++	u32	reserved0	: 4;
++	u32	dst_sel		: 1;
++	u32	src_sel		: 1;
++	u32	dst_addr_ctl	: 2;
++	u32	src_addr_ctl	: 2;
++	u32	dst_width	: 3;
++	u32	src_width	: 3;
++	u32	tc_mask		: 1;
++	u32	reserved1	: 3;
++} __attribute__((packed)) dma_llp_descr_t;
++
++#define HAL_DMAC_ENABLE() \
++	    ((DMAC_CSR_REG) |= (1<<DMAC_ENABLE_BIT_INDEX))
++
++
++#define HAL_DMAC_DISABLE() \
++	    ((DMAC_CSR_REG) &= ~(1<<DMAC_ENABLE_BIT_INDEX))
++
++
++#define HAL_DMAC_SET_MASTER0_BIG_ENDIAN() \
++	    ((DMAC_CSR_REG) |= (1<<DMAC_MASTER0_ENDIAN_BIT_INDEX))
++
++
++#define HAL_DMAC_SET_MASTER0_LITTLE_ENDIAN() \
++	    ((DMAC_CSR_REG) &= ~(1<<DMAC_MASTER0_ENDIAN_BIT_INDEX))
++
++
++#define HAL_DMAC_SET_MASTER1_BIG_ENDIAN() \
++	    ((DMAC_CSR_REG) |= (1<<DMAC_MASTER1_ENDIAN_BIT_INDEX))
++
++
++#define HAL_DMAC_SET_MASTER1_LITTLE_ENDIAN() \
++	    ((DMAC_CSR_REG) &= ~(1<<DMAC_MASTER1_ENDIAN_BIT_INDEX))
++
++#define HAL_DMAC_READ_ERROR_ABORT_INTERRUPT_STATUS(err_abt_status) \
++	    ((err_abt_status) = (DMAC_INT_ERR_STATUS_REG))
++
++
++#define HAL_DMAC_CLEAR_ERROR_ABORT_INTERRUPT_STATUS(err_abt_status) \
++	    ((DMAC_INT_ERR_STATUS_CLR_REG) = (err_abt_status))
++
++
++#define HAL_DMAC_READ_TERMINAL_COUNT_INTERRUPT_STATUS(tc_status) \
++	    ((tc_status) = (DMAC_INT_TC_STATUS_REG) & 0xFF)
++
++
++#define HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(tc_status) \
++	    ((DMAC_INT_TC_STATUS_CLR_REG) = (tc_status) & 0xFF)
++
++
++
++
++
++
++#endif	// end of #ifndef _STAR_DMAC_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_gpio.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_gpio.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_gpio.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_gpio.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,327 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_GPIO_H_
++#define	_STAR_GPIO_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	GPIOA_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSPA_GPIOA_BASE_ADDR + reg_offset)))
++#define	GPIOB_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSPA_GPIOB_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	GPIOA_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSVA_GPIOA_BASE_ADDR + reg_offset)))
++#define	GPIOB_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSVA_GPIOB_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * For GPIO Set	A
++ */
++#define	GPIOA_DATA_OUTPUT_REG			GPIOA_MEM_MAP_VALUE(0x00)
++#define	GPIOA_DATA_INPUT_REG			GPIOA_MEM_MAP_VALUE(0x04)
++#define	GPIOA_DIRECTION_REG			GPIOA_MEM_MAP_VALUE(0x08)
++
++#define	GPIOA_DATA_BIT_SET_REG			GPIOA_MEM_MAP_VALUE(0x10)
++#define	GPIOA_DATA_BIT_CLEAR_REG		GPIOA_MEM_MAP_VALUE(0x14)
++
++#define	GPIOA_INTERRUPT_ENABLE_REG		GPIOA_MEM_MAP_VALUE(0x20)
++#define	GPIOA_INTERRUPT_RAW_STATUS_REG		GPIOA_MEM_MAP_VALUE(0x24)
++#define	GPIOA_INTERRUPT_MASKED_STATUS_REG	GPIOA_MEM_MAP_VALUE(0x28)
++#define	GPIOA_INTERRUPT_MASK_REG		GPIOA_MEM_MAP_VALUE(0x2C)
++#define	GPIOA_INTERRUPT_CLEAR_REG		GPIOA_MEM_MAP_VALUE(0x30)
++#define	GPIOA_INTERRUPT_TRIGGER_METHOD_REG	GPIOA_MEM_MAP_VALUE(0x34)
++#define	GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG	GPIOA_MEM_MAP_VALUE(0x38)
++#define	GPIOA_INTERRUPT_TRIGGER_TYPE_REG	GPIOA_MEM_MAP_VALUE(0x3C)
++
++#define	GPIOA_BOUNCE_ENABLE_REG			GPIOA_MEM_MAP_VALUE(0x40)
++#define	GPIOA_BOUNCE_CLOCK_PRESCALE_REG		GPIOA_MEM_MAP_VALUE(0x44)
++
++
++/*
++ * For GPIO Set	B
++ */
++#define	GPIOB_DATA_OUTPUT_REG			GPIOB_MEM_MAP_VALUE(0x00)
++#define	GPIOB_DATA_INPUT_REG			GPIOB_MEM_MAP_VALUE(0x04)
++#define	GPIOB_DIRECTION_REG			GPIOB_MEM_MAP_VALUE(0x08)
++
++#define	GPIOB_DATA_BIT_SET_REG			GPIOB_MEM_MAP_VALUE(0x10)
++#define	GPIOB_DATA_BIT_CLEAR_REG		GPIOB_MEM_MAP_VALUE(0x14)
++
++#define	GPIOB_INTERRUPT_ENABLE_REG		GPIOB_MEM_MAP_VALUE(0x20)
++#define	GPIOB_INTERRUPT_RAW_STATUS_REG		GPIOB_MEM_MAP_VALUE(0x24)
++#define	GPIOB_INTERRUPT_MASKED_STATUS_REG	GPIOB_MEM_MAP_VALUE(0x28)
++#define	GPIOB_INTERRUPT_MASK_REG		GPIOB_MEM_MAP_VALUE(0x2C)
++#define	GPIOB_INTERRUPT_CLEAR_REG		GPIOB_MEM_MAP_VALUE(0x30)
++#define	GPIOB_INTERRUPT_TRIGGER_METHOD_REG	GPIOB_MEM_MAP_VALUE(0x34)
++#define	GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG	GPIOB_MEM_MAP_VALUE(0x38)
++#define	GPIOB_INTERRUPT_TRIGGER_TYPE_REG	GPIOB_MEM_MAP_VALUE(0x3C)
++
++#define	GPIOB_BOUNCE_ENABLE_REG			GPIOB_MEM_MAP_VALUE(0x40)
++#define	GPIOB_BOUNCE_CLOCK_PRESCALE_REG		GPIOB_MEM_MAP_VALUE(0x44)
++
++
++/*
++ * define constant macros
++ */
++
++#define	MAX_GPIO_PINS		(32)
++
++#define	GPIO_0_MASK		(1 << 0)
++#define	GPIO_1_MASK		(1 << 1)
++#define	GPIO_2_MASK		(1 << 2)
++#define	GPIO_3_MASK		(1 << 3)
++#define	GPIO_4_MASK		(1 << 4)
++#define	GPIO_5_MASK		(1 << 5)
++#define	GPIO_6_MASK		(1 << 6)
++#define	GPIO_7_MASK		(1 << 7)
++#define	GPIO_8_MASK		(1 << 8)
++#define	GPIO_9_MASK		(1 << 9)
++#define	GPIO_10_MASK		(1 << 10)
++#define	GPIO_11_MASK		(1 << 11)
++#define	GPIO_12_MASK		(1 << 12)
++#define	GPIO_13_MASK		(1 << 13)
++#define	GPIO_14_MASK		(1 << 14)
++#define	GPIO_15_MASK		(1 << 15)
++#define	GPIO_16_MASK		(1 << 16)
++#define	GPIO_17_MASK		(1 << 17)
++#define	GPIO_18_MASK		(1 << 18)
++#define	GPIO_19_MASK		(1 << 19)
++#define	GPIO_20_MASK		(1 << 20)
++#define	GPIO_21_MASK		(1 << 21)
++#define	GPIO_22_MASK		(1 << 22)
++#define	GPIO_23_MASK		(1 << 23)
++#define	GPIO_24_MASK		(1 << 24)
++#define	GPIO_25_MASK		(1 << 25)
++#define	GPIO_26_MASK		(1 << 26)
++#define	GPIO_27_MASK		(1 << 27)
++#define	GPIO_28_MASK		(1 << 28)
++#define	GPIO_29_MASK		(1 << 29)
++#define	GPIO_30_MASK		(1 << 30)
++#define	GPIO_31_MASK		(1 << 31)
++
++
++/*
++ * macro declarations for GPIO Set A
++ */
++#define	HAL_GPIOA_READ_DATA_OUT_STATUS(data_out_state) \
++    ((data_out_state) =	(GPIOA_DATA_OUTPUT_REG))
++
++#define	HAL_GPIOA_READ_DATA_IN_STATUS(data_in_state) \
++    ((data_in_state) = (GPIOA_DATA_INPUT_REG))
++
++#define	HAL_GPIOA_SET_DIRECTION_OUTPUT(gpio_index) \
++    ((GPIOA_DIRECTION_REG) |= (gpio_index))
++
++#define	HAL_GPIOA_SET_DIRECTION_INPUT(gpio_index) \
++    ((GPIOA_DIRECTION_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOA_SET_DATA_OUT_HIGH(gpio_index)	\
++    ((GPIOA_DATA_BIT_SET_REG) =	(gpio_index))
++
++#define	HAL_GPIOA_SET_DATA_OUT_LOW(gpio_index) \
++    ((GPIOA_DATA_BIT_CLEAR_REG)	= (gpio_index))
++
++#define	HAL_GPIOA_ENABLE_INTERRUPT(gpio_index) \
++    ((GPIOA_INTERRUPT_ENABLE_REG) |= (gpio_index))
++
++#define	HAL_GPIOA_DISABLE_INTERRUPT(gpio_index)	\
++    ((GPIOA_INTERRUPT_ENABLE_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOA_READ_INTERRUPT_RAW_STATUS(raw_state) \
++    ((raw_state) = (GPIOA_INTERRUPT_RAW_STATUS_REG))
++
++#define	HAL_GPIOA_READ_INTERRUPT_MASKED_STATUS(masked_raw_state) \
++    ((masked_raw_state)	= (GPIOA_INTERRUPT_MASKED_STATUS_REG))
++
++#define	HAL_GPIOA_DISABLE_INTERRUPT_MASK(gpio_index) \
++    ((GPIOA_INTERRUPT_MASK_REG)	&= ~(gpio_index))
++
++#define	HAL_GPIOA_ENABLE_INTERRUPT_MASK(gpio_index) \
++    ((GPIOA_INTERRUPT_MASK_REG)	|= (gpio_index))
++
++#define	HAL_GPIOA_CLEAR_INTERRUPT(gpio_index) \
++    ((GPIOA_INTERRUPT_CLEAR_REG) = (gpio_index))
++
++#define	HAL_GPIOA_SET_INTERRUPT_EDGE_TRIGGER_MODE(gpio_index) \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOA_SET_INTERRUPT_LEVEL_TRIGGER_MODE(gpio_index) \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index))
++
++#define	HAL_GPIOA_SET_INTERRUPT_SINGLE_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_BOTH_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG) |= (gpio_index));	\
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_SINGLE_RISING_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_TYPE_REG)	&= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_SINGLE_FALLING_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_TYPE_REG)	|= (gpio_index)); \
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_HIGH_LEVEL_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_TYPE_REG)	&= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_LOW_LEVEL_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_TYPE_REG)	|= (gpio_index)); \
++}
++
++#define	HAL_GPIOA_ENABLE_BOUNCE(gpio_index) \
++    ((GPIOA_BOUNCE_ENABLE_REG) |= (gpio_index))
++
++#define	HAL_GPIOA_DISABLE_BOUNCE(gpio_index) \
++    ((GPIOA_BOUNCE_ENABLE_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOA_READ_BOUNCE_PRESCALE_RATIO(prescale_ratio) \
++    ((prescale_ratio) =	((GPIOA_BOUNCE_CLOCK_PRESCALE_REG) & 0x0000FFFF))
++
++#define	HAL_GPIOA_WRITE_BOUNCE_PRESCALE_RATIO(prescale_ratio) \
++    ((GPIOA_BOUNCE_CLOCK_PRESCALE_REG) = (prescale_ratio & 0x0000FFFF))
++
++
++
++/*
++ * macro declarations for GPIO Set B
++ */
++#define	HAL_GPIOB_READ_DATA_OUT_STATUS(data_out_state) \
++    ((data_out_state) =	(GPIOB_DATA_OUTPUT_REG))
++
++#define	HAL_GPIOB_READ_DATA_IN_STATUS(data_in_state) \
++    ((data_in_state) = (GPIOB_DATA_INPUT_REG))
++
++#define	HAL_GPIOB_SET_DIRECTION_OUTPUT(gpio_index) \
++    ((GPIOB_DIRECTION_REG) |= (gpio_index))
++
++#define	HAL_GPIOB_SET_DIRECTION_INPUT(gpio_index) \
++    ((GPIOB_DIRECTION_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOB_SET_DATA_OUT_HIGH(gpio_index)	\
++    ((GPIOB_DATA_BIT_SET_REG) =	(gpio_index))
++
++#define	HAL_GPIOB_SET_DATA_OUT_LOW(gpio_index) \
++    ((GPIOB_DATA_BIT_CLEAR_REG)	= (gpio_index))
++
++#define	HAL_GPIOB_ENABLE_INTERRUPT(gpio_index) \
++    ((GPIOB_INTERRUPT_ENABLE_REG) |= (gpio_index))
++
++#define	HAL_GPIOB_DISABLE_INTERRUPT(gpio_index)	\
++    ((GPIOB_INTERRUPT_ENABLE_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOB_READ_INTERRUPT_RAW_STATUS(raw_state) \
++    ((raw_state) = (GPIOB_INTERRUPT_RAW_STATUS_REG))
++
++#define	HAL_GPIOB_READ_INTERRUPT_MASKED_STATUS(masked_raw_state) \
++    ((masked_raw_state)	= (GPIOB_INTERRUPT_MASKED_STATUS_REG))
++
++#define	HAL_GPIOB_DISABLE_INTERRUPT_MASK(gpio_index) \
++    ((GPIOB_INTERRUPT_MASK_REG)	&= ~(gpio_index))
++
++#define	HAL_GPIOB_ENABLE_INTERRUPT_MASK(gpio_index) \
++    ((GPIOB_INTERRUPT_MASK_REG)	|= (gpio_index))
++
++#define	HAL_GPIOB_CLEAR_INTERRUPT(gpio_index) \
++    ((GPIOB_INTERRUPT_CLEAR_REG) = (gpio_index))
++
++#define	HAL_GPIOB_SET_INTERRUPT_EDGE_TRIGGER_MODE(gpio_index) \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOB_SET_INTERRUPT_LEVEL_TRIGGER_MODE(gpio_index) \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index))
++
++#define	HAL_GPIOB_SET_INTERRUPT_SINGLE_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_BOTH_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG) |= (gpio_index));	\
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_SINGLE_RISING_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_TYPE_REG)	&= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_SINGLE_FALLING_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_TYPE_REG)	|= (gpio_index)); \
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_HIGH_LEVEL_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_TYPE_REG)	&= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_LOW_LEVEL_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_TYPE_REG)	|= (gpio_index)); \
++}
++
++#define	HAL_GPIOB_ENABLE_BOUNCE(gpio_index) \
++    ((GPIOB_BOUNCE_ENABLE_REG) |= (gpio_index))
++
++#define	HAL_GPIOB_DISABLE_BOUNCE(gpio_index) \
++    ((GPIOB_BOUNCE_ENABLE_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOB_READ_BOUNCE_PRESCALE_RATIO(prescale_ratio) \
++    ((prescale_ratio) =	((GPIOB_BOUNCE_CLOCK_PRESCALE_REG) & 0x0000FFFF))
++
++#define	HAL_GPIOB_WRITE_BOUNCE_PRESCALE_RATIO(prescale_ratio) \
++    ((GPIOB_BOUNCE_CLOCK_PRESCALE_REG) = (prescale_ratio & 0x0000FFFF))
++
++
++#endif	// end of _STAR_GPIO_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_hsdmac.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_hsdmac.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_hsdmac.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_hsdmac.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,106 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_HSDMAC_H_
++#define	_STAR_HSDMAC_H_
++
++
++#include "star_sys_memory_map.h"
++
++
++#if defined(__UBOOT__)
++#define	HSDMAC_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSPA_MISC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	HSDMAC_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSVA_MISC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	HSDMAC_CONTROL_STATUS_REG		HSDMAC_MEM_MAP_VALUE(0x040)
++
++#define	HSDMAC_MASTER0_ADDR_REG			HSDMAC_MEM_MAP_VALUE(0x050)
++
++#define	HSDMAC_MASTER1_ADDR_REG			HSDMAC_MEM_MAP_VALUE(0x054)
++
++#define	HSDMAC_LLP_REG				HSDMAC_MEM_MAP_VALUE(0x058)
++
++#define	HSDMAC_TOT_SIZE_REG			HSDMAC_MEM_MAP_VALUE(0x05C)
++
++
++#define	HAL_GET_HSDMAC_LLP_COUNTER		((HSDMAC_CONTROL_STATUS_REG >> 8) & 0xF)
++
++#define	HAL_HSDMAC_ENABLE()			((HSDMAC_CONTROL_STATUS_REG) |= (0x1))
++
++#define	HAL_HSDMAC_DISABLE()			((HSDMAC_CONTROL_STATUS_REG) &= ~(0x1))
++
++
++#define HSDMAC_MASTER0_TO_MASTER1		0
++#define HSDMAC_MASTER1_TO_MASTER0		1
++
++#define HSDMAC_RESPONSE_OK			0
++#define HSDMAC_RESPONSE_ERR			-1
++
++#define MAX_HSDMA_VEC 				32
++
++#define MAX_HSDMA_XFER_SIZE			(0xFFF << 2)
++
++struct hsdma_xfer;
++typedef struct hsdma_xfer hsdma_xfer_t;
++typedef void (*hsdma_end_io_t)(hsdma_xfer_t *hsdma_xfer, int err);
++typedef struct
++{
++	u8	data_direction;
++	u32	src_addr; // virtual
++	u32	dst_addr; // virtual
++	u32	size; // bytes
++} __attribute__((packed)) hsdma_vec_t;
++
++struct hsdma_xfer
++{
++	u8			nr_vec;
++	hsdma_vec_t		vec[MAX_HSDMA_VEC];
++	hsdma_end_io_t		hsdma_end_io;
++	void			*private;
++};
++
++/*
++ * HSDMAC LLP Descriptor object
++ */
++typedef struct
++{
++	u32	src_addr; // physical
++	u32	dst_addr; // physical
++	u32	llp;
++	u32	tot_size	: 16;//b15-b0
++	u32	reserved0	: 12;//b27-b16
++	u32	tc_mask		: 1; //b28
++	u32	data_direction	: 1; //b29
++	u32	reserved1	: 2; //b31-30
++} __attribute__((packed)) hsdma_llp_descr_t;
++
++
++#endif	// end of #ifndef _STAR_HSDMAC_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_i2c.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_i2c.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_i2c.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_i2c.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,69 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef _STAR_I2C_H_
++#define _STAR_I2C_H_
++
++#include <mach/star_sys_memory_map.h>
++
++#define I2C_MEM_MAP_ADDR(reg_offset)          (SYSVA_I2C_BASE_ADDR + reg_offset) 
++#define I2C_MEM_MAP_VALUE(reg_offset)         (*((unsigned int volatile *)I2C_MEM_MAP_ADDR(reg_offset)))
++
++#define I2C_CONTROLLER_REG_ADDR               I2C_MEM_MAP_ADDR(0x20)
++#define I2C_TIME_OUT_REG_ADDR                 I2C_MEM_MAP_ADDR(0x24)
++#define I2C_SLAVE_ADDRESS_REG_ADDR            I2C_MEM_MAP_ADDR(0x28)
++#define I2C_WRITE_DATA_REG_ADDR               I2C_MEM_MAP_ADDR(0x2C)
++#define I2C_READ_DATA_REG_ADDR                I2C_MEM_MAP_ADDR(0x30)
++#define I2C_INTERRUPT_STATUS_REG_ADDR         I2C_MEM_MAP_ADDR(0x34)
++#define I2C_INTERRUPT_ENABLE_REG_ADDR         I2C_MEM_MAP_ADDR(0x38)
++
++#define I2C_CONTROLLER_REG                    I2C_MEM_MAP_VALUE(0x20)
++#define I2C_TIME_OUT_REG                      I2C_MEM_MAP_VALUE(0x24)
++#define I2C_SLAVE_ADDRESS_REG                 I2C_MEM_MAP_VALUE(0x28)
++#define I2C_WRITE_DATA_REG                    I2C_MEM_MAP_VALUE(0x2C)
++#define I2C_READ_DATA_REG                     I2C_MEM_MAP_VALUE(0x30)
++#define I2C_INTERRUPT_STATUS_REG              I2C_MEM_MAP_VALUE(0x34)
++#define I2C_INTERRUPT_ENABLE_REG              I2C_MEM_MAP_VALUE(0x38)
++
++#define I2C_READ_ONLY_CMD      (0)
++#define I2C_WRITE_ONLY_CMD     (1)
++#define I2C_WRITE_READ_CMD     (2)
++#define I2C_READ_WRITE_CMD     (3)
++
++#define I2C_DATA_LEN_1_BYTE    (0)
++#define I2C_DATA_LEN_2_BYTE    (1)
++#define I2C_DATA_LEN_3_BYTE    (2)
++#define I2C_DATA_LEN_4_BYTE    (3)
++
++#define I2C_BUS_ERROR_FLAG     (0x1)
++#define I2C_ACTION_DONE_FLAG   (0x2)
++
++#define HAL_I2C_ENABLE_I2C()          (I2C_CONTROLLER_REG) |= ((unsigned int)0x1 << 31); 
++#define HAL_I2C_DISABLE_I2C()         (I2C_CONTROLLER_REG) &= ~((unsigned int)0x1 << 31);
++#define HAL_I2C_ENABLE_DATA_SWAP()    (I2C_CONTROLLER_REG) |= (0x1 << 24); 
++#define HAL_I2C_DISABLE_DATA_SWAP()   (I2C_CONTROLLER_REG) &= ~(0x1 << 24); 
++#define HAL_I2C_START_TRANSFER()      (I2C_CONTROLLER_REG) |= (0x1 << 6); 
++#define HAL_I2C_STOP_TRANSFER()       (I2C_CONTROLLER_REG) &= ~(0x1 << 6); 
++
++#endif
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_i2s.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_i2s.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_i2s.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_i2s.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,176 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef _STAR_I2S_H_
++#define _STAR_I2S_H_
++
++/******************************************************************************
++ * MODULE NAME:    star_i2s.h
++ * PROJECT CODE:   Orion
++ * DESCRIPTION:    
++ * MAINTAINER:     MJLIU
++ * DATE:           15 September 2005
++ *
++ * SOURCE CONTROL: 
++ *
++ * REVISION HISTORY:
++ *     15 September 2005  -  MJLIU	- Initial Version v1.0
++ *
++ *
++ * SOURCE:
++ * ISSUES:
++ * NOTES TO USERS:
++ ******************************************************************************/
++
++#include <mach/star_sys_memory_map.h>
++
++#define I2S_MEM_MAP_ADDR(reg_offset)          (SYSVA_I2S_BASE_ADDR + reg_offset) 
++#define I2S_MEM_MAP_VALUE(reg_offset)         (*((unsigned int volatile *)I2S_MEM_MAP_ADDR(reg_offset)))
++
++//#define I2S_BASE_ADDR                         (SYS_I2S_BASE_ADDR)
++
++
++/*
++ * define access macros
++ */
++#define I2S_CONFIGURATION_REG_ADDR            I2S_MEM_MAP_ADDR(0xC0)
++#define I2S_RIGHT_TRANSMIT_DATA_REG_ADDR      I2S_MEM_MAP_ADDR(0xC4)
++#define I2S_LEFT_TRANSMIT_DATA_REG_ADDR       I2S_MEM_MAP_ADDR(0xC8)
++#define I2S_RIGHT_RECEIVE_DATA_REG_ADDR       I2S_MEM_MAP_ADDR(0xCC)
++#define I2S_LEFT_RECEIVE_DATA_REG_ADDR        I2S_MEM_MAP_ADDR(0xD0)
++#define I2S_INTERRUPT_STATUS_REG_ADDR         I2S_MEM_MAP_ADDR(0xD4)
++#define I2S_INTERRUPT_ENABLE_REG_ADDR         I2S_MEM_MAP_ADDR(0xD8)
++
++#define I2S_CONFIGURATION_REG                 I2S_MEM_MAP_VALUE(0xC0)
++#define I2S_RIGHT_TRANSMIT_DATA_REG           I2S_MEM_MAP_VALUE(0xC4)
++#define I2S_LEFT_TRANSMIT_DATA_REG            I2S_MEM_MAP_VALUE(0xC8)
++#define I2S_RIGHT_RECEIVE_DATA_REG            I2S_MEM_MAP_VALUE(0xCC)
++#define I2S_LEFT_RECEIVE_DATA_REG             I2S_MEM_MAP_VALUE(0xD0)
++#define I2S_INTERRUPT_STATUS_REG              I2S_MEM_MAP_VALUE(0xD4)
++#define I2S_INTERRUPT_ENABLE_REG              I2S_MEM_MAP_VALUE(0xD8)
++
++
++/*
++ * define constants macros
++ */
++#define I2S_DATA_16_BIT             (0)
++#define I2S_DATA_32_BIT             (1)
++
++#define I2S_RXBF_R_FULL_FLAG        (0x01)
++#define I2S_TXBF_R_EMPTY_FLAG       (0x02)
++#define I2S_RXBF_L_FULL_FLAG        (0x04)
++#define I2S_TXBF_L_EMPTY_FLAG       (0x08)
++
++#define I2S_RXBF_R_OR_FLAG          (0x10)
++#define I2S_TXBF_R_UR_FLAG          (0x20)
++#define I2S_RXBF_L_OR_FLAG          (0x40)
++#define I2S_TXBF_L_UR_FLAG          (0x80)
++
++
++#define I2S_MASTER_MODE             (1)
++#define I2S_SLAVE_MODE              (0)
++
++#define I2S_I2S_MODE                (1)
++#define I2S_RJF_MODE                (2)
++#define I2S_LJF_MODE                (3)
++
++#define I2S_CLOCK_CONTINUOUS_MODE   (0)
++#define I2S_CLOCK_256S_MODE         (1)
++
++
++#define I2S_WS_RATE_32KHZ           (1)    /* 8.192 MHz */
++#define I2S_WS_RATE_44_1KHZ         (2)    /* 11.2896 MHz */
++#define I2S_WS_RATE_48KHZ           (3)    /* 12.288 MHz */
++
++
++/*
++ * define data structure
++ */
++#if 0
++typedef struct _I2S_OBJECT_    I2S_OBJECT_T;
++
++struct _I2S_OBJECT_
++{
++    u_int32          config;
++    u_int32          interrupt_config;
++
++
++    /* 
++     * For interrupt setting
++     */
++    INTC_OBJECT_T    intc_obj;
++};
++
++
++/*
++ * function declarations
++ */
++void    Hal_I2s_Initialize(I2S_OBJECT_T *);
++#endif
++
++
++/*
++ * macro declarations
++ */
++#define HAL_I2S_ENABLE_I2S() \
++{ \
++    (I2S_CONFIGURATION_REG) |= ((u32)0x1 << 31); \
++}
++
++#define HAL_I2S_DISABLE_I2S() \
++{ \
++    (I2S_CONFIGURATION_REG) &= ~((u32)0x1 << 31); \
++}
++
++#define HAL_I2S_ENABLE_DATA_SWAP() \
++{ \
++    (I2S_CONFIGURATION_REG) |= (0x1 << 24); \
++}
++
++#define HAL_I2S_DISABLE_DATA_SWAP() \
++{ \
++    (I2S_CONFIGURATION_REG) &= ~(0x1 << 24); \
++}
++
++#define HAL_I2S_DISABLE_LEFT_CHANNEL_TRANSMIT_BUFFER_UNDERRUN_INTERRUPT() \
++{ \
++    (I2S_INTERRUPT_ENABLE_REG) &= ~(I2S_TXBF_L_UR_FLAG); \
++}
++
++#define HAL_I2S_DISABLE_RIGHT_CHANNEL_TRANSMIT_BUFFER_UNDERRUN_INTERRUPT() \
++{ \
++    (I2S_INTERRUPT_ENABLE_REG) &= ~(I2S_TXBF_R_UR_FLAG); \
++}
++
++#define HAL_I2S_DISABLE_LEFT_CHANNEL_RECEIVE_BUFFER_OVERRUN_INTERRUPT() \
++{ \
++    (I2S_INTERRUPT_ENABLE_REG) &= ~(I2S_RXBF_L_OR_FLAG); \
++}
++
++#define HAL_I2S_DISABLE_RIGHT_CHANNEL_RECEIVE_BUFFER_OVERRUN_INTERRUPT() \
++{ \
++    (I2S_INTERRUPT_ENABLE_REG) &= ~(I2S_RXBF_R_OR_FLAG); \
++}
++
++
++#endif  // end of #ifndef _STAR_I2S_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_ide.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_ide.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_ide.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_ide.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,245 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_IDE_H_
++#define	_STAR_IDE_H_
++
++
++#include "star_sys_memory_map.h"
++
++
++#if defined(__UBOOT__)
++#define	IDE_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_IDE_CONTROLLER_BASE_ADDR + reg_offset)))
++#define	IDE_BUS_MEM_MAP_VALUE(reg_offset)	(*((u8 volatile *)(SYSPA_IDE_DEVICE_BASE_ADDR + reg_offset)))
++#define IDE_DATA_MEM_MAP_VALUE(reg_offset)	(*((u16 volatile *)(SYSPA_IDE_DEVICE_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	IDE_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_IDE_CONTROLLER_BASE_ADDR + reg_offset)))
++#define	IDE_BUS_MEM_MAP_VALUE(reg_offset)	(*((u8 volatile *)(SYSVA_IDE_DEVICE_BASE_ADDR + reg_offset)))
++#define IDE_DATA_MEM_MAP_VALUE(reg_offset)	(*((u16 volatile *)(SYSVA_IDE_DEVICE_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * IDE Controller Registers
++ */
++#define IDE_PIO_CONTROL_REG			IDE_MEM_MAP_VALUE(0x00)
++#define IDE_DRIVE0_PIO_TIMING_CONFIG_REG	IDE_MEM_MAP_VALUE(0x04)
++#define IDE_DRIVE1_PIO_TIMING_CONFIG_REG	IDE_MEM_MAP_VALUE(0x08)
++#define IDE_DRIVE0_DMA_TIMING_CONFIG_REG	IDE_MEM_MAP_VALUE(0x0C)
++#define IDE_DRIVE1_DMA_TIMING_CONFIG_REG	IDE_MEM_MAP_VALUE(0x10)
++#define IDE_UDMA_TIMING_CONFIG_REG		IDE_MEM_MAP_VALUE(0x14)
++#define IDE_DMA_UDMA_CONTROL_REG		IDE_MEM_MAP_VALUE(0x18)
++#define IDE_STATUS_CONTROL_REG			IDE_MEM_MAP_VALUE(0x1C)
++#define IDE_BUS_MASTER_DTP_REG			IDE_MEM_MAP_VALUE(0x20)
++#define IDE_FAST_PATH_ACCESS_WINDOW_REG		IDE_MEM_MAP_VALUE(0x24)
++#define IDE_FAST_PATH_DMA_BURST_SIZE_REG	IDE_MEM_MAP_VALUE(0x28)
++
++
++/*
++ * IDE Command Block Registers
++ */
++#define _IDE_DATA_REG				IDE_DATA_MEM_MAP_VALUE(0x20)
++#define _IDE_ERROR_REG				IDE_BUS_MEM_MAP_VALUE(0x24)
++#define _IDE_FEATURES_REG			IDE_BUS_MEM_MAP_VALUE(0x24)
++#define _IDE_SECTOR_COUNT_REG			IDE_BUS_MEM_MAP_VALUE(0x28)
++#define _IDE_LBA_LOW_REG			IDE_BUS_MEM_MAP_VALUE(0x2C)
++#define _IDE_LBA_MID_REG			IDE_BUS_MEM_MAP_VALUE(0x30)
++#define _IDE_LBA_HIGH_REG			IDE_BUS_MEM_MAP_VALUE(0x34)
++#define _IDE_DEVICE_REG				IDE_BUS_MEM_MAP_VALUE(0x38)
++#define _IDE_COMMAND_REG			IDE_BUS_MEM_MAP_VALUE(0x3C)
++#define _IDE_STATUS_REG				IDE_BUS_MEM_MAP_VALUE(0x3C)
++
++
++/*
++ * IDE Control Block Registers
++ */
++#define IDE_DEVICE_CONTROL_REG			IDE_BUS_MEM_MAP_VALUE(0x40)
++#define IDE_ALTERNATE_STATUS_REG		IDE_BUS_MEM_MAP_VALUE(0x40)
++
++
++#define IDE_CD					(0x01)
++#define IDE_IO					(0x02)
++#define IDE_REL					(0x04)
++#define IDE_OVL					(0x02)
++#define IDE_BSY					(0x80)
++#define IDE_DRQ					(0x08)
++#define IDE_SERV				(0x10)
++#define IDE_DMRD				(0x20)
++#define IDE_ERR					(0x01)
++#define IDE_SRST				(0x04)
++
++/*
++ * macro declarations for IDE Controller
++ */
++#define HAL_IDE_DRIVE0_IORDY_SAMPLE_ENABLE() \
++{ \
++    (IDE_PIO_CONTROL_REG) |= (0x1 << 0); \
++}
++
++#define HAL_IDE_DRIVE0_IORDY_SAMPLE_DISABLE() \
++{ \
++    (IDE_PIO_CONTROL_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_IDE_DRIVE1_IORDY_SAMPLE_ENABLE() \
++{ \
++    (IDE_PIO_CONTROL_REG) |= (0x1 << 1); \
++}
++
++#define HAL_IDE_DRIVE1_IORDY_SAMPLE_DISABLE() \
++{ \
++    (IDE_PIO_CONTROL_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_IDE_DRIVE0_UDMA_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 0); \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 2); \
++}
++
++#define HAL_IDE_DRIVE0_UDMA_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_IDE_DRIVE1_UDMA_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 1); \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 3); \
++}
++
++#define HAL_IDE_DRIVE1_UDMA_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_IDE_DRIVE0_DMA_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 2); \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_IDE_DRIVE0_DMA_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 2); \
++}
++
++#define HAL_IDE_DRIVE1_DMA_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 3); \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_IDE_TO_USB_FAST_PATH_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 4); \
++}
++
++#define HAL_IDE_TO_USB_FAST_PATH_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 4); \
++}
++
++#define HAL_IDE_DRIVE1_DMA_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 3); \
++}
++
++#define HAL_IDE_DMA_UDMA_START() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1); \
++}
++
++#define HAL_IDE_DMA_UDMA_STOP() \
++{ \
++    (IDE_STATUS_CONTROL_REG) &= ~(0x1); \
++}
++
++#define HAL_IDE_CLEAR_PRD_INTERRUPT_STATUS() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1 << 2); \
++}
++
++#define HAL_IDE_CLEAR_INTRQ_INTERRUPT_STATUS() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1 << 1); \
++}
++
++#define HAL_IDE_HOST_TRANSFER_WRITE_OUT() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1 << 3); \
++}
++
++#define HAL_IDE_HOST_TRANSFER_READ_IN() \
++{ \
++    (IDE_STATUS_CONTROL_REG) &= ~(0x1 << 3); \
++}
++
++#define HAL_IDE_MASK_PRD_INTERRUPT() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1 << 6); \
++}
++
++#define HAL_IDE_UNMASK_PRD_INTERRUPT() \
++{ \
++    (IDE_STATUS_CONTROL_REG) &= ~(0x1 << 6); \
++}
++
++#define HAL_IDE_SET_DESCRIPTOR_TABLE_POINTER(dtp) \
++{ \
++    (IDE_BUS_MASTER_DTP_REG) = (dtp); \
++}
++
++#define HAL_IDE_SET_FAST_PATH_ACCESS_WINDOW(fp_access_window) \
++{ \
++    (IDE_FAST_PATH_ACCESS_WINDOW_REG) = (fp_access_window); \
++}
++
++/*
++ * macro declarations for IDE Device
++ */
++#define HAL_IDE_SELECT_DEVICE_0() \
++{ \
++    (_IDE_DEVICE_REG) = 0; \
++}
++
++#define HAL_IDE_SELECT_DEVICE_1() \
++{ \
++    (_IDE_DEVICE_REG) = (0x1 << 4); \
++}
++
++#define HAL_IDE_ENABLE_DEVICE_INTRQ() \
++{ \
++    (IDE_DEVICE_CONTROL_REG) = (0); \
++}
++
++#define HAL_IDE_DISABLE_DEVICE_INTRQ() \
++{ \
++    (IDE_DEVICE_CONTROL_REG) = (0x2); \
++}
++
++
++#endif  // end of #ifndef _STAR_IDE_H_
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_intc.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_intc.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_intc.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_intc.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,328 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_INTC_H_
++#define	_STAR_INTC_H_
++
++
++//#include <mach/star_sys_memory_map.h>
++#include <mach/star_sys_memory_map.h>
++
++#if defined(__UBOOT__)
++#define	INTC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_VIC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	INTC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_VIC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	INTC_INTERRUPT_RAW_STATUS_REG		INTC_MEM_MAP_VALUE(0x000)
++#define	INTC_EDGE_INTERRUPT_SOURCE_CLEAR_REG	INTC_MEM_MAP_VALUE(0x004)
++#define	INTC_INTERRUPT_MASK_REG			INTC_MEM_MAP_VALUE(0x008)
++#define	INTC_INTERRUPT_MASK_CLEAR_REG		INTC_MEM_MAP_VALUE(0x00C)
++#define	INTC_INTERRUPT_TRIGGER_MODE_REG		INTC_MEM_MAP_VALUE(0x010)
++#define	INTC_INTERRUPT_TRIGGER_LEVEL_REG	INTC_MEM_MAP_VALUE(0x014)
++#define	INTC_FIQ_SELECT_REG			INTC_MEM_MAP_VALUE(0x018)
++#define	INTC_IRQ_STATUS_REG			INTC_MEM_MAP_VALUE(0x01C)
++#define	INTC_FIQ_STATUS_REG			INTC_MEM_MAP_VALUE(0x020)
++#define	INTC_SOFTWARE_INTERRUPT_REG		INTC_MEM_MAP_VALUE(0x024)
++#define	INTC_SOFTWARE_INTERRUPT_CLEAR_REG	INTC_MEM_MAP_VALUE(0x028)
++#define	INTC_SOFTWARE_PRIORITY_MASK_REG		INTC_MEM_MAP_VALUE(0x02C)
++#define	INTC_POWER_MANAGEMENT_INTERRUPT_REG	INTC_MEM_MAP_VALUE(0x034)
++
++#define	INTC_VECTOR_ADDRESS_0_REG		INTC_MEM_MAP_VALUE(0x040)
++#define	INTC_VECTOR_ADDRESS_1_REG		INTC_MEM_MAP_VALUE(0x044)
++#define	INTC_VECTOR_ADDRESS_2_REG		INTC_MEM_MAP_VALUE(0x048)
++#define	INTC_VECTOR_ADDRESS_3_REG		INTC_MEM_MAP_VALUE(0x04C)
++#define	INTC_VECTOR_ADDRESS_4_REG		INTC_MEM_MAP_VALUE(0x050)
++#define	INTC_VECTOR_ADDRESS_5_REG		INTC_MEM_MAP_VALUE(0x054)
++#define	INTC_VECTOR_ADDRESS_6_REG		INTC_MEM_MAP_VALUE(0x058)
++#define	INTC_VECTOR_ADDRESS_7_REG		INTC_MEM_MAP_VALUE(0x05C)
++#define	INTC_VECTOR_ADDRESS_8_REG		INTC_MEM_MAP_VALUE(0x060)
++#define	INTC_VECTOR_ADDRESS_9_REG		INTC_MEM_MAP_VALUE(0x064)
++#define	INTC_VECTOR_ADDRESS_10_REG		INTC_MEM_MAP_VALUE(0x068)
++#define	INTC_VECTOR_ADDRESS_11_REG		INTC_MEM_MAP_VALUE(0x06C)
++#define	INTC_VECTOR_ADDRESS_12_REG		INTC_MEM_MAP_VALUE(0x070)
++#define	INTC_VECTOR_ADDRESS_13_REG		INTC_MEM_MAP_VALUE(0x074)
++#define	INTC_VECTOR_ADDRESS_14_REG		INTC_MEM_MAP_VALUE(0x078)
++#define	INTC_VECTOR_ADDRESS_15_REG		INTC_MEM_MAP_VALUE(0x07C)
++#define	INTC_VECTOR_ADDRESS_16_REG		INTC_MEM_MAP_VALUE(0x080)
++#define	INTC_VECTOR_ADDRESS_17_REG		INTC_MEM_MAP_VALUE(0x084)
++#define	INTC_VECTOR_ADDRESS_18_REG		INTC_MEM_MAP_VALUE(0x088)
++#define	INTC_VECTOR_ADDRESS_19_REG		INTC_MEM_MAP_VALUE(0x08C)
++#define	INTC_VECTOR_ADDRESS_20_REG		INTC_MEM_MAP_VALUE(0x090)
++#define	INTC_VECTOR_ADDRESS_21_REG		INTC_MEM_MAP_VALUE(0x094)
++#define	INTC_VECTOR_ADDRESS_22_REG		INTC_MEM_MAP_VALUE(0x098)
++#define	INTC_VECTOR_ADDRESS_23_REG		INTC_MEM_MAP_VALUE(0x09C)
++#define	INTC_VECTOR_ADDRESS_24_REG		INTC_MEM_MAP_VALUE(0x0A0)
++#define	INTC_VECTOR_ADDRESS_25_REG		INTC_MEM_MAP_VALUE(0x0A4)
++#define	INTC_VECTOR_ADDRESS_26_REG		INTC_MEM_MAP_VALUE(0x0A8)
++#define	INTC_VECTOR_ADDRESS_27_REG		INTC_MEM_MAP_VALUE(0x0AC)
++#define	INTC_VECTOR_ADDRESS_28_REG		INTC_MEM_MAP_VALUE(0x0B0)
++#define	INTC_VECTOR_ADDRESS_29_REG		INTC_MEM_MAP_VALUE(0x0B4)
++#define	INTC_VECTOR_ADDRESS_30_REG		INTC_MEM_MAP_VALUE(0x0B8)
++#define	INTC_VECTOR_ADDRESS_31_REG		INTC_MEM_MAP_VALUE(0x0BC)
++
++#define	INTC_INTERRUPT_PRIORITY_0_REG		INTC_MEM_MAP_VALUE(0x0C0)
++#define	INTC_INTERRUPT_PRIORITY_1_REG		INTC_MEM_MAP_VALUE(0x0C4)
++#define	INTC_INTERRUPT_PRIORITY_2_REG		INTC_MEM_MAP_VALUE(0x0C8)
++#define	INTC_INTERRUPT_PRIORITY_3_REG		INTC_MEM_MAP_VALUE(0x0CC)
++#define	INTC_INTERRUPT_PRIORITY_4_REG		INTC_MEM_MAP_VALUE(0x0D0)
++#define	INTC_INTERRUPT_PRIORITY_5_REG		INTC_MEM_MAP_VALUE(0x0D4)
++#define	INTC_INTERRUPT_PRIORITY_6_REG		INTC_MEM_MAP_VALUE(0x0D8)
++#define	INTC_INTERRUPT_PRIORITY_7_REG		INTC_MEM_MAP_VALUE(0x0DC)
++#define	INTC_INTERRUPT_PRIORITY_8_REG		INTC_MEM_MAP_VALUE(0x0E0)
++#define	INTC_INTERRUPT_PRIORITY_9_REG		INTC_MEM_MAP_VALUE(0x0E4)
++#define	INTC_INTERRUPT_PRIORITY_10_REG		INTC_MEM_MAP_VALUE(0x0E8)
++#define	INTC_INTERRUPT_PRIORITY_11_REG		INTC_MEM_MAP_VALUE(0x0EC)
++#define	INTC_INTERRUPT_PRIORITY_12_REG		INTC_MEM_MAP_VALUE(0x0F0)
++#define	INTC_INTERRUPT_PRIORITY_13_REG		INTC_MEM_MAP_VALUE(0x0F4)
++#define	INTC_INTERRUPT_PRIORITY_14_REG		INTC_MEM_MAP_VALUE(0x0F8)
++#define	INTC_INTERRUPT_PRIORITY_15_REG		INTC_MEM_MAP_VALUE(0x0FC)
++#define	INTC_INTERRUPT_PRIORITY_16_REG		INTC_MEM_MAP_VALUE(0x100)
++#define	INTC_INTERRUPT_PRIORITY_17_REG		INTC_MEM_MAP_VALUE(0x104)
++#define	INTC_INTERRUPT_PRIORITY_18_REG		INTC_MEM_MAP_VALUE(0x108)
++#define	INTC_INTERRUPT_PRIORITY_19_REG		INTC_MEM_MAP_VALUE(0x10C)
++#define	INTC_INTERRUPT_PRIORITY_20_REG		INTC_MEM_MAP_VALUE(0x110)
++#define	INTC_INTERRUPT_PRIORITY_21_REG		INTC_MEM_MAP_VALUE(0x114)
++#define	INTC_INTERRUPT_PRIORITY_22_REG		INTC_MEM_MAP_VALUE(0x118)
++#define	INTC_INTERRUPT_PRIORITY_23_REG		INTC_MEM_MAP_VALUE(0x11C)
++#define	INTC_INTERRUPT_PRIORITY_24_REG		INTC_MEM_MAP_VALUE(0x120)
++#define	INTC_INTERRUPT_PRIORITY_25_REG		INTC_MEM_MAP_VALUE(0x124)
++#define	INTC_INTERRUPT_PRIORITY_26_REG		INTC_MEM_MAP_VALUE(0x128)
++#define	INTC_INTERRUPT_PRIORITY_27_REG		INTC_MEM_MAP_VALUE(0x12C)
++#define	INTC_INTERRUPT_PRIORITY_28_REG		INTC_MEM_MAP_VALUE(0x130)
++#define	INTC_INTERRUPT_PRIORITY_29_REG		INTC_MEM_MAP_VALUE(0x134)
++#define	INTC_INTERRUPT_PRIORITY_30_REG		INTC_MEM_MAP_VALUE(0x138)
++#define	INTC_INTERRUPT_PRIORITY_31_REG		INTC_MEM_MAP_VALUE(0x13C)
++
++#define	INTC_IRQ_VECTOR_ADDRESS_REG		INTC_MEM_MAP_VALUE(0x140)
++
++#define	INTC_VECTOR_INTERRUPT_ENABLE_REG	INTC_MEM_MAP_VALUE(0x144)
++
++
++
++/*
++ * define constants macros
++ */
++#define	INTC_TIMER1_BIT_INDEX			(0)
++#define	INTC_TIMER2_BIT_INDEX			(1)
++
++#define	INTC_CLOCK_SCALE_BIT_INDEX		(2)
++
++#define	INTC_WATCHDOG_TIMER_BIT_INDEX		(3)
++
++#define	INTC_GPIO_EXTERNAL_INT_BIT_INDEX	(4)
++
++#define	INTC_PCI_INTA_BIT_INDEX			(5)
++#define	INTC_PCI_INTB_BIT_INDEX			(6)
++#define	INTC_PCI_BROKEN_BIT_INDEX		(7)
++#define	INTC_PCI_AHB2BRIDGE_BIT_INDEX		(8)
++
++#define	INTC_UART0_BIT_INDEX			(9)
++#define	INTC_UART1_BIT_INDEX			(10)
++
++#define	INTC_GDMAC_TC_BIT_INDEX			(11)
++#define	INTC_GDMAC_ERROR_BIT_INDEX		(12)
++
++#define	INTC_PCMCIA_BRIDGE_BIT_INDEX		(13)
++
++#define	INTC_RTC_BIT_INDEX			(14)
++
++#define	INTC_PCM_BIT_INDEX			(15)
++
++#define	INTC_USB20_DEVICE_BIT_INDEX		(16)
++
++#define	INTC_IDE_BIT_INDEX			(17)
++
++#define	INTC_NIC_STATUS_BIT_INDEX		(18)
++#define	INTC_NIC_TXTC_BIT_INDEX			(19)
++#define	INTC_NIC_RXRC_BIT_INDEX			(20)
++#define	INTC_NIC_TXQE_BIT_INDEX			(21)
++#define	INTC_NIC_RXQF_BIT_INDEX			(22)
++
++#define	INTC_USB11_BIT_INDEX			(23)
++#define	INTC_USB20_BIT_INDEX			(24)
++
++#define	INTC_I2S_BIT_INDEX			(25)
++#define	INTC_SPI_BIT_INDEX			(26)
++#define	INTC_I2C_BIT_INDEX			(27)
++
++#define	INTC_USB_DEVICE_VBUS_BIT_INDEX		(28)
++
++#define	INTC_EXT_INT29_BIT_INDEX		(29)
++#define	INTC_EXT_INT30_BIT_INDEX		(30)
++#define	INTC_HSDMAC_BIT_INDEX			(31)
++
++
++/*
++ * define interrupt types
++ */
++#define	INTC_IRQ_INTERRUPT			(0)
++#define	INTC_FIQ_INTERRUPT			(1)
++
++/*
++ * define interrupt trigger mode
++ */
++#define	INTC_LEVEL_TRIGGER			(0)
++#define	INTC_EDGE_TRIGGER			(1)
++
++/*
++ * define rising/falling edge for edge trigger mode
++ */
++#define	INTC_RISING_EDGE			(0)
++#define	INTC_FALLING_EDGE			(1)
++
++/*
++ * define active High/Low for level trigger mode
++ */
++#define	INTC_ACTIVE_HIGH			(0)
++#define	INTC_ACTIVE_LOW				(1)
++
++/*
++ * macro declarations
++ */
++#define	HAL_INTC_READ_INTERRUPT_RAW_STATUS(int_raw_status) \
++{ \
++    (int_raw_status) = (INTC_INTERRUPT_RAW_STATUS_REG);	\
++}
++
++
++#define	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(source_bit_index)	\
++{ \
++    (INTC_EDGE_INTERRUPT_SOURCE_CLEAR_REG) = (1	<< source_bit_index); \
++}
++
++
++#define	HAL_INTC_READ_INTERRUPT_MASK(int_mask) \
++{ \
++    (int_mask) = (INTC_INTERRUPT_MASK_REG); \
++}
++
++
++#define	HAL_INTC_WRITE_INTERRUPT_MASK(int_mask)	\
++{ \
++    (INTC_INTERRUPT_MASK_REG) =	(int_mask); \
++}
++
++
++#define	HAL_INTC_DISABLE_INTERRUPT_SOURCE(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_MASK_REG) =	(1 << source_bit_index); \
++}
++
++
++#define	HAL_INTC_ENABLE_INTERRUPT_SOURCE(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_MASK_CLEAR_REG) = (1 << source_bit_index); \
++}
++
++
++#define	HAL_INTC_SET_EDGE_TRIGGER_MODE(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_MODE_REG) |= (1 << source_bit_index);\
++}
++
++
++#define	HAL_INTC_SET_LEVEL_TRIGGER_MODE(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_MODE_REG) &= (~(1 << source_bit_index)); \
++}
++
++
++#define	HAL_INTC_SET_RISING_EDGE_TRIGGER_LEVEL(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_LEVEL_REG) &= (~(1 << source_bit_index)); \
++}
++
++
++#define	HAL_INTC_SET_FALLING_EDGE_TRIGGER_LEVEL(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_LEVEL_REG) |= (1 <<	source_bit_index); \
++}
++
++
++#define	HAL_INTC_SET_ACTIVE_HIGH_TRIGGER_LEVEL(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_LEVEL_REG) &= (~(1 << source_bit_index));\
++}
++
++
++#define	HAL_INTC_SET_ACTIVE_LOW_TRIGGER_LEVEL(source_bit_index)	\
++{ \
++    (INTC_INTERRUPT_TRIGGER_LEVEL_REG) |= ((1 << source_bit_index)); \
++}
++
++
++#define	HAL_INTC_ASSIGN_INTERRUPT_TO_IRQ(source_bit_index) \
++{ \
++    (INTC_FIQ_SELECT_REG) &= (~(1 << source_bit_index)); \
++}
++
++
++#define	HAL_INTC_ASSIGN_INTERRUPT_TO_FIQ(source_bit_index) \
++{ \
++    (INTC_FIQ_SELECT_REG) |= (1	<< source_bit_index); \
++}
++
++
++#define	HAL_INTC_READ_IRQ_STATUS(int_irq_status) \
++{ \
++    (int_irq_status) = (INTC_IRQ_STATUS_REG); \
++}
++
++
++#define	HAL_INTC_READ_FIQ_STATUS(int_fiq_status) \
++{ \
++    (int_fiq_status) = (INTC_FIQ_STATUS_REG); \
++}
++
++
++#define	HAL_INTC_READ_SOFTWARE_INTERRUPT(software_interrupt) \
++{ \
++    (software_interrupt) = (INTC_SOFTWARE_INTERRUPT_REG); \
++}
++
++
++#define	HAL_INTC_ENABLE_SOFTWARE_INTERRUPT(source_bit_index) \
++{ \
++    (INTC_SOFTWARE_INTERRUPT_REG) = (1 << source_bit_index); \
++}
++
++
++#define	HAL_INTC_CLEAR_SOFTWARE_INTERRUPT(source_bit_index) \
++{ \
++    (INTC_SOFTWARE_INTERRUPT_CLEAR_REG)	= (1 <<	source_bit_index); \
++}
++
++
++#define	HAL_INTC_SELECT_INTERRUPT_SOURCE_FOR_SLEEP_WAKEUP(source_bit_index) \
++{ \
++    (INTC_POWER_MANAGEMENT_INTERRUPT_REG) = (1 << source_bit_index); \
++}
++
++#endif	// end of #ifndef _STAR_INTC_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_misc.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_misc.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_misc.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_misc.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,402 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_MISC_H_
++#define	_STAR_MISC_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	MISC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_MISC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	MISC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_MISC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	MISC_MEMORY_REMAP_REG				MISC_MEM_MAP_VALUE(0x00)
++#define	MISC_CHIP_CONFIG_REG				MISC_MEM_MAP_VALUE(0x04)
++#define	MISC_DEBUG_PROBE_DATA_REG			MISC_MEM_MAP_VALUE(0x08)
++#define	MISC_DEBUG_PROBE_SELECTION_REG			MISC_MEM_MAP_VALUE(0x0C)
++#define	MISC_PCI_CONTROL_BROKEN_MASK_REG		MISC_MEM_MAP_VALUE(0x10)
++#define	MISC_PCI_BROKEN_STATUS_REG			MISC_MEM_MAP_VALUE(0x14)
++#define	MISC_PCI_DEVICE_VENDOR_ID_REG			MISC_MEM_MAP_VALUE(0x18)
++#define	MISC_USB_HOST_PHY_CONTROL_TEST_REG		MISC_MEM_MAP_VALUE(0x1C)
++#define	MISC_GPIOA_PIN_ENABLE_REG			MISC_MEM_MAP_VALUE(0x20)
++#define	MISC_GPIOB_PIN_ENABLE_REG			MISC_MEM_MAP_VALUE(0x24)
++#define	MISC_GPIOA_RESISTOR_CONFIG_REG			MISC_MEM_MAP_VALUE(0x28)
++#define	MISC_GPIOA_DRIVE_STRENGTH_CONFIG_REG		MISC_MEM_MAP_VALUE(0x2C)
++#define	MISC_FAST_ETHERNET_PHY_CONFIG_REG		MISC_MEM_MAP_VALUE(0x30)
++#define	MISC_SOFTWARE_TEST_1_REG			MISC_MEM_MAP_VALUE(0x38)
++#define	MISC_SOFTWARE_TEST_2_REG			MISC_MEM_MAP_VALUE(0x3C)
++
++#define	MISC_E_FUSE_0_REG				MISC_MEM_MAP_VALUE(0x60)
++#define	MISC_E_FUSE_1_REG				MISC_MEM_MAP_VALUE(0x64)
++
++
++/*
++ * define constants macros
++ */
++#define	MISC_PARALLEL_FLASH_BOOT		(0)
++#define	MISC_SPI_SERIAL_FLASH_BOOT		(1)
++
++#define	MISC_LITTLE_ENDIAN			(0)
++#define	MISC_BIG_ENDIAN				(1)
++
++#define	MISC_FARADAY_ICE			(0)
++#define	MISC_ARM_ICE				(1)
++
++#define	MISC_EXT_INT29_PINS			((0x1 << 0))
++#define	MISC_EXT_INT30_PINS			((0x1 << 1))
++#define	MISC_EXT_INT31_PINS			((0x1 << 2))
++#define	MISC_I2C_PINS				((0x1 << 13) | (0x1 << 14))
++#define	MISC_I2S_PINS				((0x1 << 15) | (0x1 << 16) | (0x1 << 17))
++#define	MISC_PCM_PINS				((0x1 << 18) | (0x1 << 19) | (0x1 << 20) | (0x1 << 21))
++#define	MISC_LED0_PINS				((0x1 << 22))
++#define	MISC_LED1_PINS				((0x1 << 23))
++#define	MISC_LED2_PINS				((0x1 << 24))
++#define	MISC_LED012_PINS			((0x1 << 22) | (0x1 << 23) | (0x1 << 24))
++#define	MISC_WDTIMER_RESET_PINS			((0x1 << 25))
++#define	MISC_SPI_PINS				((0x1 << 26) | (0x1 << 27) | (0x1 << 28) | (0x1 << 29) | (0x1 << 30) | (0x1 << 31))
++#define	MISC_MDC_MDIO_PINS			((0x1 << 0) | (0x1 << 1))
++#define	MISC_NIC_COL_PINS			((0x1 << 2))
++#define	MISC_IDE_PINS				((0xFF << 3))
++#define	MISC_SRAM_BANK1_PINS			((0x1 << 11) | (0x1 << 14))
++#define	MISC_SRAM_BANK2_PINS			((0x1 << 12) | (0x1 << 15))
++#define	MISC_SRAM_BANK3_PINS			((0x1 << 13) | (0x1 << 16))
++#define	MISC_PCMCIA_PINS			((0x1 << 17) | (0x1 << 18) | (0x1 << 19) | (0x1 << 20))
++#define	MISC_UART1_PINS				((0x1 << 21) | (0x1 << 22))
++#define	MISC_PCI_PINS				(((u32)0x1FF << 23))
++
++#define	MISC_UART0_ACT0_Pin			(0x1 << 2)
++#define	MISC_UART1_ACT1_Pin			(0x1 << 3)
++
++#define	MISC_GPIOA_PIN_0			(0)
++#define	MISC_GPIOA_PIN_1			(1)
++#define	MISC_GPIOA_PIN_2			(2)
++#define	MISC_GPIOA_PIN_3			(3)
++#define	MISC_GPIOA_PIN_4			(4)
++#define	MISC_GPIOA_PIN_5			(5)
++#define	MISC_GPIOA_PIN_6			(6)
++#define	MISC_GPIOA_PIN_7			(7)
++#define	MISC_GPIOA_PIN_8			(8)
++#define	MISC_GPIOA_PIN_9			(9)
++#define	MISC_GPIOA_PIN_10			(10)
++
++#define	MISC_GPIOA_75K_RESISTOR_PULL_DOWN	(1)
++#define	MISC_GPIOA_75K_RESISTOR_PULL_UP		(2)
++#define	MISC_GPIOA_75K_RESISTOR_PULL_KEEPER	(3)
++
++#define	MISC_GPIOA_DRIVE_STRENGTH_4MA		(0)
++#define	MISC_GPIOA_DRIVE_STRENGTH_8MA		(1)
++
++
++/*
++ * macro declarations
++ */
++#define	HAL_MISC_ENABLE_SPI_SERIAL_FLASH_BANK_ACCESS() \
++{ \
++    (MISC_CHIP_CONFIG_REG) |= (0x1 << 4); \
++}
++
++#define	HAL_MISC_DISABLE_SPI_SERIAL_FLASH_BANK_ACCESS()	\
++{ \
++    (MISC_CHIP_CONFIG_REG) &= ~(0x1 << 4); \
++}
++
++
++/*
++ * Macro defines for GPIOA and GPIOB Pin Enable	Register
++ */
++#define	HAL_MISC_ENABLE_EXT_INT29_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_EXT_INT29_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_EXT_INT29_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_EXT_INT29_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_EXT_INT30_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_EXT_INT30_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_EXT_INT30_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_EXT_INT30_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_I2C_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_I2C_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_I2C_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_I2C_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_I2S_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_I2S_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_I2S_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_I2S_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_PCM_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_PCM_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_PCM_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_PCM_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_LED0_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_LED0_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_LED0_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_LED0_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_LED1_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_LED1_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_LED1_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_LED1_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_LED2_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_LED2_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_LED2_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_LED2_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_LED012_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_LED012_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_LED012_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_LED012_PINS);	\
++}
++
++#define	HAL_MISC_ENABLE_WDTIMER_RESET_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_WDTIMER_RESET_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_WDTIMER_RESET_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_WDTIMER_RESET_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_SPI_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_SPI_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_SPI_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_SPI_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_UART0_ACT0_PIN() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_UART0_ACT0_Pin); \
++}
++
++#define	HAL_MISC_DISABLE_UART0_ACT0_PIN() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_UART0_ACT0_Pin); \
++}
++
++#define	HAL_MISC_ENABLE_UART1_ACT1_PIN() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_UART1_ACT1_Pin); \
++}
++
++#define	HAL_MISC_DISABLE_UART1_ACT1_PIN() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_UART1_ACT1_Pin); \
++}
++
++#define	HAL_MISC_ENABLE_MDC_MDIO_PINS()	\
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_MDC_MDIO_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_MDC_MDIO_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_MDC_MDIO_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_NIC_COL_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_NIC_COL_PINS);	\
++}
++
++#define	HAL_MISC_DISABLE_NIC_COL_PINS()	\
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_NIC_COL_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_IDE_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_IDE_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_IDE_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_IDE_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_SRAM_BANK1_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_SRAM_BANK1_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_SRAM_BANK1_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_SRAM_BANK1_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_SRAM_BANK2_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_SRAM_BANK2_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_SRAM_BANK2_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_SRAM_BANK2_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_SRAM_BANK3_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_SRAM_BANK3_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_SRAM_BANK3_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_SRAM_BANK3_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_PCMCIA_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_PCMCIA_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_PCMCIA_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_PCMCIA_PINS);	\
++}
++
++#define	HAL_MISC_ENABLE_UART1_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_UART1_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_UART1_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_UART1_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_PCI_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_PCI_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_PCI_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_PCI_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_ALL_SHARED_GPIO_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	= (0x0); \
++    (MISC_GPIOB_PIN_ENABLE_REG)	= (0x0); \
++}
++
++#define	HAL_MISC_DISABLE_ALL_SHARED_GPIO_PINS()	\
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	= (0xFFFFFFFF);	\
++    (MISC_GPIOB_PIN_ENABLE_REG)	= (0xFFFFFFFF);	\
++}
++
++#define	HAL_MISC_CONFIGURE_GPIOA_RESISTOR(pin_index, value) \
++{ \
++    (MISC_GPIOA_RESISTOR_CONFIG_REG) &=	~(0x3 << (2 * pin_index)); \
++    (MISC_GPIOA_RESISTOR_CONFIG_REG) |=	((value	& 0x3) << (2 * pin_index)); \
++}
++
++#define	HAL_MISC_CONFIGURE_GPIOA_DRIVE_STRENGTH(pin_index, value) \
++{ \
++    (MISC_GPIOA_DRIVE_STRENGTH_CONFIG_REG) &= ~(0x1 << pin_index); \
++    (MISC_GPIOA_DRIVE_STRENGTH_CONFIG_REG) |= (value <<	pin_index); \
++}
++
++#define	HAL_MISC_SELECT_FAST_ETHERNET_PHY_LED_MODE0() \
++{ \
++    (MISC_FAST_ETHERNET_PHY_CONFIG_REG)	= (0x0); \
++}
++
++#define	HAL_MISC_SELECT_FAST_ETHERNET_PHY_LED_MODE1() \
++{ \
++    (MISC_FAST_ETHERNET_PHY_CONFIG_REG)	= (0x1); \
++}
++
++#define	HAL_MISC_SELECT_FAST_ETHERNET_PHY_LED_MODE2() \
++{ \
++    (MISC_FAST_ETHERNET_PHY_CONFIG_REG)	= (0x2); \
++}
++
++#define	HAL_MISC_SELECT_FAST_ETHERNET_PHY_LED_MODE3() \
++{ \
++    (MISC_FAST_ETHERNET_PHY_CONFIG_REG)	= (0x3); \
++}
++
++
++#endif	// end of #ifndef _STAR_MISC_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_nic.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_nic.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_nic.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_nic.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,346 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_NIC_H_
++#define	_STAR_NIC_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	NIC_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSPA_NIC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	NIC_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSVA_NIC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	NIC_PHY_CONTROL_REG0			NIC_MEM_MAP_VALUE(0x000)
++#define	NIC_PHY_CONTROL_REG1			NIC_MEM_MAP_VALUE(0x004)
++
++#define	NIC_MAC_CONTROL_REG			NIC_MEM_MAP_VALUE(0x008)
++#define	NIC_FLOW_CONTROL_CONFIG_REG		NIC_MEM_MAP_VALUE(0x00C)
++
++#define	NIC_ARL_CONFIG_REG			NIC_MEM_MAP_VALUE(0x010)
++
++#define	NIC_MY_MAC_HIGH_BYTE_REG		NIC_MEM_MAP_VALUE(0x014)
++#define	NIC_MY_MAC_LOW_BYTE_REG			NIC_MEM_MAP_VALUE(0x018)
++
++#define	NIC_HASH_TABLE_CONTROL_REG		NIC_MEM_MAP_VALUE(0x01C)
++
++#define	NIC_MY_VLANID_CONTROL_REG		NIC_MEM_MAP_VALUE(0x020)
++
++#define	NIC_MY_VLANID_0_1			NIC_MEM_MAP_VALUE(0x024)
++#define	NIC_MY_VLANID_2_3			NIC_MEM_MAP_VALUE(0x028)
++
++#define	NIC_DMA_CONFIG_REG			NIC_MEM_MAP_VALUE(0x030)
++#define	NIC_TX_DMA_CONTROL_REG			NIC_MEM_MAP_VALUE(0x034)
++#define	NIC_RX_DMA_CONTROL_REG			NIC_MEM_MAP_VALUE(0x038)
++#define	NIC_TX_DESC_PTR_REG			NIC_MEM_MAP_VALUE(0x03C)
++#define	NIC_RX_DESC_PTR_REG			NIC_MEM_MAP_VALUE(0x040)
++
++#define	NIC_TX_DESC_BASE_ADDR_REG		NIC_MEM_MAP_VALUE(0x044)
++#define	NIC_RX_DESC_BASE_ADDR_REG		NIC_MEM_MAP_VALUE(0x048)
++#define	NIC_DELAYED_INT_CONFIG_REG		NIC_MEM_MAP_VALUE(0x04C)
++
++#define	NIC_INT_STATUS_REG			NIC_MEM_MAP_VALUE(0x050)
++#define	NIC_INT_MASK_REG			NIC_MEM_MAP_VALUE(0x054)
++
++#define	NIC_TEST_0_REG				NIC_MEM_MAP_VALUE(0x058)
++#define	NIC_TEST_1_REG				NIC_MEM_MAP_VALUE(0x05C)
++
++#define	NIC_MIB_RX_OK_PKT_CNTR			NIC_MEM_MAP_VALUE(0x100)
++#define	NIC_MIB_RX_OK_BYTE_CNTR			NIC_MEM_MAP_VALUE(0x104)
++#define	NIC_MIB_RX_RUNT_BYTE_CNTR		NIC_MEM_MAP_VALUE(0x108)
++#define	NIC_MIB_RX_OSIZE_DROP_PKT_CNTR		NIC_MEM_MAP_VALUE(0x10C)
++
++#define	NIC_MIB_RX_NO_BUF_DROP_PKT_CNTR		NIC_MEM_MAP_VALUE(0x110)
++
++#define	NIC_MIB_RX_CRC_ERR_PKT_CNTR		NIC_MEM_MAP_VALUE(0x114)
++
++#define	NIC_MIB_RX_ARL_DROP_PKT_CNTR		NIC_MEM_MAP_VALUE(0x118)
++
++#define	NIC_MIB_MYVLANID_MISMATCH_DROP_PKT_CNTR	NIC_MEM_MAP_VALUE(0x11C)
++
++#define	NIC_MIB_RX_CHKSUM_ERR_PKT_CNTR		NIC_MEM_MAP_VALUE(0x120)
++
++#define	NIC_MIB_RX_PAUSE_FRAME_PKT_CNTR		NIC_MEM_MAP_VALUE(0x124)
++
++#define	NIC_MIB_TX_OK_PKT_CNTR			NIC_MEM_MAP_VALUE(0x128)
++#define	NIC_MIB_TX_OK_BYTE_CNTR			NIC_MEM_MAP_VALUE(0x12C)
++
++#define	NIC_MIB_TX_COLLISION_CNTR		NIC_MEM_MAP_VALUE(0x130)
++#define	NIC_MIB_TX_PAUSE_FRAME_CNTR		NIC_MEM_MAP_VALUE(0x130)
++
++#define	NIC_MIB_TX_FIFO_UNDERRUN_RETX_CNTR	NIC_MEM_MAP_VALUE(0x134)
++
++
++
++
++/*
++ * define constants macros
++ */
++
++#define	NIC_PHY_ADDRESS		1 //the phy addr const	value
++#define	NIC_PHY_ID		0x0243	//the phy id
++
++#define	GW_NIC_MAX_TFD_NUM	(32)
++#define	GW_NIC_MAX_RFD_NUM	(32)
++#define	MAX_BUFFERS		(64)
++
++
++
++#define	MMU_OFF			(0)
++#define	MMU_ON			(1)
++#define	OS_NULL			(0)
++
++
++#define	NET_BUFFER_PACKET_SIZE		(512)
++#define	NET_BUFFER_SHIFT_BIT_NUM	(9)	// 2*n9=512
++
++#define	MAX_PACKET_LEN		(1536)
++
++#define	INTERNAL_LOOPBACK_MODE	(1)
++#define	SOFTWARE_REPEATER_MODE	(2)
++
++#define	TXTC_INT_BIT		(0x08000000)
++#define	TX_INSV_BIT		(0x04000000)
++
++#define	LS_BIT			(0x10000000)
++#define	FS_BIT			(0x20000000)
++#define	EOR_BIT			(0x40000000)
++#define	FS_LS_BIT		(0x30000000)
++#define	C_BIT			(0x80000000)
++#define	FS_LS_C_BIT		(0xB0000000)
++#define	FS_LS_INT_BIT		(0x38000000)
++
++
++
++// HASH	TABLE CONTROL REGISTER
++#define	NIC_HASH_TABLE_BIST_DONE_BIT	(0x1 <<	17)
++#define	NIC_HASH_TABLE_BIST_OK_BIT	(0x1 <<	16)
++#define	NIC_HASH_COMMAND_START_BIT	(0x1 <<	14)
++#define	NIC_HASH_COMMAND_BIT		(0x1 <<	13)
++#define	NIC_HASH_BIT_DATA		(0x1 <<	12)
++#define	NIC_HASH_BIT_ADDRESS_BIT	(0x1ff)
++
++
++#define	NIC_REG_CNT			((0x48 << 2) + 1)
++
++/*
++ * macro access
++ */
++
++#define	GW_NIC_TX_TFD_NEXT(work_tfd_ptr) \
++    work_tfd_ptr = NIC_TX_TFD_Ring.head	+ (((u32)(work_tfd_ptr - NIC_TX_TFD_Ring.head) + 1) % GW_NIC_MAX_TFD_NUM)
++
++
++#define	GW_NIC_TX_TFD_PREVIOUS(work_tfd_ptr) \
++    work_tfd_ptr = NIC_TX_TFD_Ring.head	+ ((GW_NIC_MAX_TFD_NUM + (u32)(work_tfd_ptr - NIC_TX_TFD_Ring.head) - 1) % GW_NIC_MAX_TFD_NUM)
++
++
++#define	GW_NIC_RX_RFD_NEXT(work_rfd_ptr) \
++    work_rfd_ptr = NIC_RX_RFD_Ring.head	+ (((u32)(work_rfd_ptr - NIC_RX_RFD_Ring.head) + 1) % GW_NIC_MAX_RFD_NUM)
++
++
++#define	GW_NIC_RX_RFD_PREVIOUS(work_rfd_ptr) \
++    work_rfd_ptr = NIC_RX_RFD_Ring.head	+ ((GW_NIC_MAX_RFD_NUM + (u32)(work_rfd_ptr - NIC_RX_RFD_Ring.head) - 1) % GW_NIC_MAX_RFD_NUM)
++
++
++/*
++ * PHY register	defines
++ */
++#define	PHY_MII_CONTROL_REG_ADDR		0x00
++#define	PHY_MII_STATUS_REG_ADDR			0x01
++#define	PHY_ID1_REG_ADDR			0x02
++#define	PHY_ID2_REG_ADDR			0x03
++#define	PHY_AN_ADVERTISEMENT_REG_ADDR		0x04
++#define	PHY_AN_REAMOTE_CAP_REG_ADDR		0x05
++
++
++#define	PHY_RESERVED1_REG_ADDR			0x10
++#define	PHY_RESERVED2_REG_ADDR			0x11
++#define	PHY_CH_STATUS_OUTPUT_REG_ADDR		0x12
++#define	PHY_RESERVED3_REG_ADDR			0x13
++#define	PHY_RESERVED4_REG_ADDR			0x14
++
++
++#define	PHY_SPEC_CONTROL_REG_ADDR		0x16
++#define	PHY_INTC_CONTROL_STATUS_REG_ADDR	0x17
++
++/*
++ * NIC registers access	macros defines
++ */
++
++//0x004
++#define	HAL_NIC_WRITE_PHY_CONTROL1(config_value) \
++    ((NIC_PHY_CONTROL_REG1) = (config_value))
++
++#define	HAL_NIC_READ_PHY_CONTROL1(config_value)	\
++    ((config_value) = (NIC_PHY_CONTROL_REG1))
++
++//0x008
++#define	HAL_NIC_WRITE_MAC_CONFIGURATION(config_value) \
++    ((NIC_MAC_CONTROL_REG) = (config_value))
++
++#define	HAL_NIC_READ_MAC_CONFIGURATION(config_value) \
++    ((config_value) = (NIC_MAC_CONTROL_REG))
++
++//0x00C
++#define	HAL_NIC_WRITE_FLOW_CONTROL_CONFIG(fc_cfg) \
++    ((NIC_FLOW_CONTROL_CONFIG_REG) = (fc_cfg))
++
++#define	HAL_NIC_READ_FLOW_CONTROL_CONFIG(fc_cfg) \
++    ((fc_cfg) =	(NIC_FLOW_CONTROL_CONFIG_REG))
++
++//0x010
++#define	HAL_NIC_WRITE_ARL_CONFIGURATION(cfg) \
++    ((NIC_ARL_CONFIG_REG) = (cfg))
++
++#define	HAL_NIC_READ_ARL_CONFIGURATION(cfg) \
++    ((cfg) = (NIC_ARL_CONFIG_REG))
++
++//0x014,
++#define	HAL_NIC_WRITE_MY_MAC_HIGH_BYTE(cfg) \
++    ((NIC_MY_MAC_HIGH_BYTE_REG)	= (cfg & 0x0000FFFF ) )
++
++#define	HAL_NIC_READ_MY_MAC_HIGH_BYTE(cfg) \
++    ((cfg) = (NIC_MY_MAC_HIGH_BYTE_REG & 0x0000FFFF ))
++
++//0x018
++#define	HAL_NIC_WRITE_MY_MAC_LOW_BYTE(cfg) \
++    ((NIC_MY_MAC_LOW_BYTE_REG) = (cfg))
++
++#define	HAL_NIC_READ_MY_MAC_LOW_BYTE(cfg) \
++    ((cfg) = (NIC_MY_MAC_LOW_BYTE_REG))
++
++//0x03C
++#define	HAL_NIC_READ_INTERRUPT_STATUS(int_status) \
++    ((int_status) = (NIC_INT_STATUS_REG))
++
++#define	HAL_NIC_CLEAR_ALL_INTERRUPT_STATUS_SOURCES()\
++    ((NIC_INT_STATUS_REG) = (0xFFFFFFFF))
++
++#define	HAL_NIC_CLEAR_INTERRUPT_STATUS_SOURCES(source) \
++    ((NIC_INT_STATUS_REG) |= (source))
++
++#define	HAL_NIC_CLEAR_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++    ((NIC_INT_STATUS_REG) |= (1	<< (source_bit_index)))
++
++//0x040
++#define	HAL_NIC_DISABLE_ALL_INTERRUPT_STATUS_SOURCES() \
++    ((NIC_INT_MASK_REG)	= (0xFFFFFFFF))
++
++#define	HAL_NIC_ENABLE_ALL_INTERRUPT_STATUS_SOURCES() \
++    ((NIC_INT_MASK_REG)	= (0x00000000))
++
++#define	HAL_NIC_DISABLE_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++    ((NIC_INT_MASK_REG)	|= (1 << (source_bit_index)))
++
++#define	HAL_NIC_ENABLE_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++    ((NIC_INT_MASK_REG)	&= ~(1 << (source_bit_index)))
++
++//0x44
++#define	HAL_NIC_WRITE_TEST0_REG(cfg) \
++    ((NIC_TEST_0_REG) =	(cfg))
++
++#define	HAL_NIC_READ_TEST0_REG(cfg) \
++    ((cfg) = (NIC_TEST_0_REG))
++
++//0x48
++#define	HAL_NIC_WRITE_TEST1_REG(cfg) \
++    ((NIC_TEST_1_REG) =	(cfg))
++
++#define	HAL_NIC_READ_TEST1_REG(cfg) \
++    ((cfg) = (NIC_TEST_1_REG))
++
++
++
++/*
++ * NIC's DMA macros defines
++ */
++#define	HAL_NIC_TX_DMA_START() \
++    ((NIC_TX_DMA_CONTROL_REG) =	(1))
++
++
++#define	HAL_NIC_TX_DMA_STOP() \
++    ((NIC_TX_DMA_CONTROL_REG) =	(0))
++
++
++#define	HAL_NIC_READ_TX_DMA_STATE(state) \
++    ((state) = (NIC_TX_DMA_CONTROL_REG))
++
++
++#define	HAL_NIC_RX_DMA_START() \
++    ((NIC_RX_DMA_CONTROL_REG) =	(1))
++
++
++#define	HAL_NIC_RX_DMA_STOP() \
++    ((NIC_RX_DMA_CONTROL_REG) =	(0))
++
++
++#define	HAL_NIC_WRITE_TXSD(tssd_value) \
++    ((NIC_TX_DESC_PTR_REG) = (tssd_value))
++
++
++#define	HAL_NIC_READ_TXSD(tssd_value) \
++    ((tssd_value) = (NIC_TX_DESC_PTR_REG))
++
++
++#define	HAL_NIC_WRITE_RXSD(fssd_value) \
++    ((NIC_RX_DESC_PTR_REG) = (fssd_value))
++
++
++#define	HAL_NIC_READ_RXSD(fssd_value) \
++    ((fssd_value) = (NIC_RX_DESC_PTR_REG))
++
++
++#define	HAL_NIC_WRITE_TX_BASE(ts_base_value) \
++    ((NIC_TX_DESC_BASE_ADDR_REG) = (ts_base_value))
++
++
++#define	HAL_NIC_READ_TX_BASE(ts_base_value) \
++    ((ts_base_value) = (NIC_TX_DESC_BASE_ADDR_REG))
++
++
++#define	HAL_NIC_WRITE_RX_BASE(fs_base_value) \
++    ((NIC_RX_DESC_BASE_ADDR_REG) = (fs_base_value))
++
++
++#define	HAL_NIC_READ_RX_BASE(fs_base_value) \
++    ((fs_base_value) = (NIC_RX_DESC_BASE_ADDR_REG))
++
++
++#define	HAL_NIC_WRITE_DELAYED_INTERRUPT_CONFIG(delayed_interrupt_config) \
++    ((NIC_DELAYED_INT_CONFIG_REG) = (delayed_interrupt_config))
++
++
++#define	HAL_NIC_READ_DELAYED_INTERRUPT_CONFIG(delayed_interrupt_config)	\
++    ((delayed_interrupt_config)	= (NIC_DELAYED_INT_CONFIG_REG))
++
++#endif	// end of #ifndef _STAR_NIC_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_pci_bridge.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_pci_bridge.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_pci_bridge.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_pci_bridge.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,132 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_PCI_DRIDGE_H_
++#define	_STAR_PCI_DRIDGE_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#define	PCI_IO_SPACE_BASE_ADDR			(SYSPA_PCI_IO_SPACE_BASE_ADDR)
++#define PCI_IO_SPACE_SIZE			0x08000000 /* 64MB */
++#define PCI_IO_SPACE_START			PCI_IO_SPACE_BASE_ADDR
++#define PCI_IO_SPACE_END			(PCI_IO_SPACE_BASE_ADDR + PCI_IO_SPACE_SIZE - 1)
++#define	PCI_MEMORY_SPACE_BASE_ADDR		(SYSPA_PCI_MEMORY_SPACE_BASE_ADDR)
++#define PCI_MEMORY_SPACE_SIZE			0x10000000 /* 256MB */
++#define PCI_NPREFETCH_MEMORY_SPACE_START	PCI_MEMORY_SPACE_BASE_ADDR
++#define PCI_NPREFETCH_MEMORY_SPACE_SIZE		0x00800000 /* 8MB */
++#define PCI_NPREFETCH_MEMORY_SPACE_END		(PCI_NPREFETCH_MEMORY_SPACE_START + PCI_NPREFETCH_MEMORY_SPACE_SIZE - 1)
++#define PCI_PREFETCH_MEMORY_SPACE_START		(PCI_NPREFETCH_MEMORY_SPACE_START + PCI_NPREFETCH_MEMORY_SPACE_SIZE)
++#define PCI_PREFETCH_MEMORY_SPACE_SIZE		0x00800000 /* 8MB */
++#define PCI_PREFETCH_MEMORY_SPACE_END		(PCI_PREFETCH_MEMORY_SPACE_START + PCI_PREFETCH_MEMORY_SPACE_SIZE - 1)
++
++
++#if defined(__UBOOT__)
++#define	PCIB_MEM_MAP_VALUE(base, reg_offset)	(*((u32 volatile *)(SYSPA_PCI_##base##_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	PCIB_MEM_MAP_VALUE(base, reg_offset)	(*((u32 volatile *)(SYSVA_PCI_##base##_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	PCI_BRIDGE_CONFIG_DATA			PCIB_MEM_MAP_VALUE(CONFIG_DATA_BASE, 0x2C)
++#define	PCI_BRIDGE_CONFIG_ADDR			PCIB_MEM_MAP_VALUE(CONFIG_ADDR_BASE, 0x28)
++
++#define PCI_BRIDGE_CONFIG_DATA_REG_OFFSET	0x2C
++#define PCI_BRIDGE_CONFIG_ADDR_REG_OFFSET	0x28
++
++/*
++ * define constants macros
++ */
++#define	PCIB_BUS_CLOCK_33M			1
++
++#define	PCIB_BUS_CLOCK_66M			2
++
++#define	PCIB_DEVICE_ID				0x8131
++
++#define	PCIB_VENDOR_ID				0xEEEE
++
++#define	PCIB_CLASS_CODE				0xFF0000
++
++#define	PCIB_REVISION_ID			0x00
++
++#define	PCIB_BAR0_MEMORY_SPACE_BASE		0x20000000
++
++#define	PCIB_BAR1_IO_SPACE_BASE			0x20000000
++
++
++#define	PCI_MEMORY_SPACE_BASE			0xB0000000
++
++#define	PCI_IO_SPACE_BASE			0xA8000000
++
++
++#define	PCI_MAX_BUS_NUM				0x01
++#define	PCI_MAX_DEVICE_NUM			0x14
++#define	PCI_MAX_FUNCTION_NUM			0x01
++#define	PCI_MAX_REG_NUM				0x3C
++
++
++#define	PCI_MAX_DEVICE_TYPE_NUM			0x13
++#define	PCI_MAX_BAR_NUM				0x06
++
++
++#define	PCI_CSH_VENDOR_ID_REG_ADDR		0x00
++#define	PCI_CSH_DEVICE_ID_REG_ADDR		0x02
++#define	PCI_CSH_COMMAND_REG_ADDR		0x04
++#define	PCI_CSH_STATUS_REG_ADDR			0x06
++#define	PCI_CSH_REVISION_CLASS_REG_ADDR		0x08
++#define	PCI_CSH_CACHE_LINE_SIZE_REG_ADDR	0x0C
++#define	PCI_CSH_LATENCY_TIMER_REG_ADDR		0x0D
++#define	PCI_CSH_HEADER_TYPE_REG_ADDR		0x0E
++#define	PCI_CSH_BIST_REG_ADDR			0x0F
++#define	PCI_CSH_BAR_REG_ADDR			0x10
++
++
++#define	PCI_IO_SPACE_SIZE_1M			0x00
++#define	PCI_IO_SPACE_SIZE_2M			0x01
++#define	PCI_IO_SPACE_SIZE_4M			0x02
++#define	PCI_IO_SPACE_SIZE_8M			0x03
++#define	PCI_IO_SPACE_SIZE_16M			0x04
++#define	PCI_IO_SPACE_SIZE_32M			0x05
++#define	PCI_IO_SPACE_SIZE_64M			0x06
++#define	PCI_IO_SPACE_SIZE_128M			0x07
++#define	PCI_IO_SPACE_SIZE_256M			0x08
++#define	PCI_IO_SPACE_SIZE_512M			0x09
++#define	PCI_IO_SPACE_SIZE_1G			0x0A
++#define	PCI_IO_SPACE_SIZE_2G			0x0B
++
++
++#define	PCI_MEMORY_SPACE_TYPE			0
++#define	PCI_IO_SPACE_TYPE			1
++
++#define	PCI_BROKEN_FLAG				1
++#define	PCI_AHB2PCIB_FLAG			2
++
++
++#endif	// end of #ifndef _STAR_PCI_DRIDGE_H_
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_pcmcia_bridge.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_pcmcia_bridge.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_pcmcia_bridge.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_pcmcia_bridge.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,231 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_PCMCIA_DRIDGE_H_
++#define	_STAR_PCMCIA_DRIDGE_H_
++
++/******************************************************************************
++ * MODULE NAME:	   star_pcmcia_bridge.h
++ * PROJECT CODE:   Equuleus
++ * DESCRIPTION:
++ * MAINTAINER:	   Eric	Yang
++ * DATE:	   15 September	2005
++ *
++ * SOURCE CONTROL:
++ *
++ * LICENSE:
++ *     This source code	is copyright (c) 2005 Star Semi	Inc.
++ *     All rights reserved.
++ *
++ * REVISION HISTORY:
++ *     15 September 2005  -  Eric Yang	- Initial Version v1.0
++ *
++ *
++ * SOURCE:
++ * ISSUES:
++ * NOTES TO USERS:
++ ******************************************************************************/
++
++#include "star_sys_memory_map.h"
++
++
++#if defined(__UBOOT__)
++#define	PCMCIA_BRIDGE_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_PCMCIA_CONTROL_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	PCMCIA_BRIDGE_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_PCMCIA_CONTROL_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	PCMCIA_CONFIGURATION_REG			PCMCIA_BRIDGE_MEM_MAP_VALUE(0x20)
++#define	PCMCIA_MEMORY_ACCESS_TIMING_PARAM_REG		PCMCIA_BRIDGE_MEM_MAP_VALUE(0x24)
++#define	PCMCIA_IO_ACCESS_TIMING_PARAM_REG		PCMCIA_BRIDGE_MEM_MAP_VALUE(0x28)
++
++
++#define	PCMCIA_ATTRIBUTE_MEMORY_SPACE_BASE_ADDR		(SYSPA_PCMCIA_ATTRIBUTE_MEMORY_BASE_ADDR)
++#define	PCMCIA_COMMOM_MEMORY_SPACE_BASE_ADDR		(SYSPA_PCMCIA_COMMON_MEMORY_BASE_ADDR)
++#define	PCMCIA_IO_SPACE_BASE_ADDR			(SYSPA_PCMCIA_IO_SPACE_BASE_ADDR)
++
++
++
++/*
++ * define constants macros
++ */
++#define	PCMCIA_DATA_BUS_WIDTH_8		(0)
++
++#define	PCMCIA_DATA_BUS_WIDTH_16	(1)
++
++
++/*
++ * Flags for PCMCIA_STATUS
++ */
++#define	FLAG_STATUS_BVD1		0x01
++#define	FLAG_STATUS_STSCHG		0x01
++#define	FLAG_STATUS_BVD2		0x02
++#define	FLAG_STATUS_SPKR		0x02
++#define	FLAG_STATUS_DETECT		0xf3	  /* bit 2=0,3=0 ,0x0c bit 2=1,3=1 */
++#define	FLAG_STATUS_WRPROT		0x10
++#define	FLAG_STATUS_READY		0x20
++#define	FLAG_STATUS_INPACK		0x40
++
++
++/*
++ * Flags for PCMCIA_CSC
++ */
++#define	FLAG_CSC_BVD1			0x01
++#define	FLAG_CSC_BVD2			0x02
++#define	FLAG_CSC_READY			0x04
++#define	FLAG_CSC_INPACK			0x08
++#define	FLAG_CSC_STSCHG			0x10
++#define	FLAG_CSC_CARDINT		0x20
++#define	FLAG_CSC_DETECT			0x40
++#define	FLAG_CSC_SWCDC			0x80
++
++
++/*
++ * Flags for PCMCIA_POWER
++ */
++#define	FLAG_POWER_OFF			0x00	  /* Turn off the socket */
++#define	FLAG_POWER_3V			0x01	  /* 1:Vcc = 3.3v 0:Vcc	= 5.0v */
++#define	FLAG_POWER_SWH			0x02	  /* Direct 5V/3V switch enable	*/
++#define	FLAG_POWER_CTL			0x10	  /* Socket power control */
++#define	FLAG_POWER_AUTO			0x20	  /* Auto power	switch enable */
++#define	FLAG_POWER_OUTENA		0x40	  /* Output enable */
++
++
++/*
++ * Flags for PCMCIA_GBLCTL
++ */
++#define	FLAG_GBLCTL_PWRDOWN		0x01
++#define	FLAG_GBLCTL_WBACK		0x02
++#define	FLAG_GBLCTL_16BITS		0x04
++#define	FLAG_GBLCTL_IOCARD		0x08
++#define	FLAG_GBLCTL_SWCDINT		0x10
++#define	FLAG_GBLCTL_RESET		0x20
++
++
++/*
++ * Flags for PCMCIA_INTCFG
++ */
++#define	FLAG_INTCFG_BDEAD		0x01
++#define	FLAG_INTCFG_BWARN		0x02
++#define	FLAG_INTCFG_READY		0x04
++#define	FLAG_INTCFG_INPACK		0x08
++#define	FLAG_INTCFG_LEVEL		0x10
++#define	FLAG_INTCFG_FEDGE		0x20
++#define	FLAG_INTCFG_REDGE		0x30
++#define	FLAG_INTCFG_DETECT		0x40
++#define	FLAG_INTCFG_STSCHG		0x80
++
++
++/*
++ * Definitions for Card	Status flags for GetStatus
++ */
++#define	STATUS_BATDEAD			0x0001
++#define	STATUS_BATWARN			0x0002
++#define	STATUS_DETECT			0x0004
++#define	STATUS_WRPROT			0x0008
++#define	STATUS_READY			0x0010
++#define	STATUS_INPACK			0x0020
++#define	STATUS_STSCHG			0x0040    /* just for	CSC */
++#define	SOFTWARE_STATUS_DETECT		0x0040    /* just for	CSC */
++
++
++/*
++ * Set Socket configuration flags
++ */
++#define	SS_PWR_AUTO			0x0001
++#define	SS_PWR_SWH			0x0002
++#define	SS_PWR_SEL			0x0004
++#define	SS_POWER_ON			0x0008
++#define	SS_OUTPUT_ENA			0x0010
++#define	SS_IOCARD			0x0020
++#define	SS_RESET			0x0040
++#define	SS_WBACK			0x0080
++#define	SS_16BITS			0x0100
++#define	SS_PWR_DOWN_MODE		0x0200
++#define	SS_SWCDINT			0x0400
++
++
++/*
++ * Set Interrupt Configuration flags
++ */
++#define	INTR_BATDEAD			0x0001
++#define	INTR_BATWARN			0x0002
++#define	INTR_READY			0x0004
++#define	INTR_INPACK			0x0008
++#define	INTR_CARDINT			0x0010
++#define	INTR_DETECT			0x0020
++#define	INTR_STSCHG			0x0040
++
++
++/*
++ * tuple code
++ */
++#define	CISTPL_NULL			0x00
++#define	CISTPL_DEVICE			0x01
++#define	CISTPL_NO_LINK			0x14
++#define	CISTPL_VERS_1			0x15
++#define	CISTPL_CONFIG			0x1a
++#define	CISTPL_CFTABLE_ENTRY		0x1b
++#define	CISTPL_MANFID			0x20
++#define	CISTPL_END			0xff
++
++
++/*
++ * Return codes
++ */
++#define	CS_SUCCESS			0x00
++#define	CS_UNSUPPORTED_FUNCTION		0x15
++#define	CS_NO_MORE_ITEMS		0x1f
++#define	CS_BAD_TUPLE			0x40
++
++
++/*
++ * Attributes for tuple	calls
++ */
++#define	TUPLE_RETURN_LINK		0x01
++#define	TUPLE_RETURN_COMMON		0x02
++
++#define	RETURN_FIRST_TUPLE		0xff
++
++
++/*
++ * macro declarations
++ */
++#define	HAL_PCMCIA_ENABLE_PCMCIA_CONTROLLER() \
++{ \
++    (PCMCIA_CONFIGURATION_REG) |= (0x1 << 1); \
++}
++
++#define	HAL_PCMCIA_DISABLE_PCMCIA_CONTROLLER() \
++{ \
++    (PCMCIA_CONFIGURATION_REG) &= ~(0x1	<< 1); \
++}
++
++
++#endif	// end of #ifndef _STAR_PCMCIA_DRIDGE_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_pcm.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_pcm.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_pcm.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_pcm.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,277 @@
++/******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef _STAR_PCM_H_
++#define _STAR_PCM_H_
++
++/******************************************************************************
++ * MODULE NAME:    star_pcm.h
++ * PROJECT CODE:   Orion
++ * DESCRIPTION:    
++ * MAINTAINER:     MJLIU
++ * DATE:           15 September 2005
++ *
++ * SOURCE CONTROL: 
++ *
++ * LICENSE:
++ *     This source code is copyright (c) 2005 Star Semi Inc.
++ *     All rights reserved.
++ *
++ * REVISION HISTORY:
++ *     15 September 2005  -  MJLIU	- Initial Version v1.0
++ *
++ *
++ * SOURCE:
++ * ISSUES:
++ * NOTES TO USERS:
++ ******************************************************************************/
++
++#include <mach/star_sys_memory_map.h>
++
++#define PCM_BASE_ADDR                         (SYSVA_PCM_BASE_ADDR)
++#define PCM_MEM_MAP_ADDR(reg_offset)          (PCM_BASE_ADDR + reg_offset)
++#define PCM_MEM_MAP_VALUE(reg_offset)         (*((u32 volatile *)PCM_MEM_MAP_ADDR(reg_offset)))
++
++
++/*
++ * define access macros
++ */
++#define PCM_CONFIGURATION_0_REG               PCM_MEM_MAP_VALUE(0x80)
++#define PCM_CONFIGURATION_1_REG               PCM_MEM_MAP_VALUE(0x84)
++
++#define PCM_CHANNEL_0_CONFIG_REG              PCM_MEM_MAP_VALUE(0x88)
++#define PCM_CHANNEL_1_CONFIG_REG              PCM_MEM_MAP_VALUE(0x8C)
++#define PCM_CHANNEL_2_CONFIG_REG              PCM_MEM_MAP_VALUE(0x90)
++#define PCM_CHANNEL_3_CONFIG_REG              PCM_MEM_MAP_VALUE(0x94)
++
++#define PCM_TX_DATA_31_0_REG                  PCM_MEM_MAP_VALUE(0x98)
++#define PCM_TX_DATA_63_32_REG                 PCM_MEM_MAP_VALUE(0x9C)
++
++#define PCM_RX_DATA_31_0_REG                  PCM_MEM_MAP_VALUE(0xA0)
++#define PCM_RX_DATA_63_32_REG                 PCM_MEM_MAP_VALUE(0xA4)
++
++#define PCM_INTERRUPT_STATUS_REG              PCM_MEM_MAP_VALUE(0xA8)
++#define PCM_INTERRUPT_ENABLE_REG              PCM_MEM_MAP_VALUE(0xAC)
++
++
++
++/*
++ * define constants macros
++ */
++#define CH0_BIT_INDEX                         (0x1)
++#define CH1_BIT_INDEX                         (0x2)
++#define CH2_BIT_INDEX                         (0x4)
++#define CH3_BIT_INDEX                         (0x8)
++
++#define PCM_RXBUF_FULL_FG                     (0x1)
++#define PCM_TXBUF_EMPTY_FG                    (0x2)
++#define PCM_RXBUF_OVERRUN_FG                  (0x4)
++#define PCM_TXBUF_UNDERRUN_FG                 (0x8)
++
++#define PCM_ENABLE_FG                         (0x1 << 23)
++
++#define PCM_IDL_MODE                          (0)
++#define PCM_GCI_MODE                          (1)
++
++#define PCM_DATA_BIT_8                        (0)
++#define PCM_DATA_BIT_16                       (1)
++
++
++/*
++ * Set Commands Variables
++ */
++#define        Software_Reset                               (0x02)
++#define        Hardware_Reset                               (0x04)
++#define        Write_Transmit_Time_Slot                     (0x40)
++#define        Read_Transmit_Time_Slot                      (0x41)
++#define        Write_Receive_Time_Slot                      (0x42)
++#define        Read_Receive_Time_Slot                       (0x43)
++#define        Write_Tx_Rx_CLK_Slot_Tx_CLK_Edge             (0x44)
++#define        Read_Tx_Rx_CLK_Slot_Tx_CLK_Edge              (0x45)
++#define        Write_Device_Configure_Reg                   (0x46)
++#define        Read_Device_Configure_Reg                    (0x47)
++#define        Write_Channel_Enable_Operating_Mode_Reg      (0x4A)
++#define        Read_Channel_Enable_Operating_Mode_Reg       (0x4B)
++#define        Read_Signal_Reg                              (0x4D)
++#define        Input_Data_Reg                               (0x52)
++#define        Output_Data_Reg                              (0x53)
++#define        Input_Direction_Reg                          (0x54)
++#define        Output_Direction_Reg                         (0x55)
++#define        Write_System_State                           (0x56)
++#define        Read_System_State                            (0x57)
++#define        Write_Operating_Functon                      (0x60)
++#define        Read_Operating_Functon                       (0x61)
++#define        Write_System_State_Config                    (0x68)
++#define        Read_System_State_Config                     (0x69)
++#define        Write_Interrupt_Mask_Reg                     (0x6C)
++#define        Read_Interrupt_Mask_Reg                      (0x6D)
++#define        Write_Operating_Condition                    (0x70)
++#define        Write_Loop_Supervision_Parameter             (0xC2)
++#define        Write_DC_Feed_Parameter                      (0xC6)
++#define        Write_Signal_A_B_Parameter                   (0xD2)
++#define        Write_Switching_Reg_Parameter                (0xE4)
++#define        Write_Switching_Reg_Control                  (0xE6)
++
++
++/*
++ * define data structure
++ */
++typedef struct _PCM_CHANNEL_OBJECT_    PCM_CHANNEL_OBJECT_T;
++
++struct _PCM_CHANNEL_OBJECT_
++{
++    u16          channel_0_tx_data;
++    u16          channel_0_rx_data;
++    u32          channel_0_data_width;     /* 0 : 8-bit, 1 : 16-bit */
++
++    u16          channel_1_tx_data;
++    u16          channel_1_rx_data;
++    u32          channel_1_data_width;
++
++    u16          channel_2_tx_data;
++    u16          channel_2_rx_data;
++    u32          channel_2_data_width;
++
++    u16          channel_3_tx_data;
++    u16          channel_3_rx_data;
++    u32          channel_3_data_width;
++    
++    u32          channel_enable_config;    /* bit[0] = 0 : channel 0 disabled
++                                                     [0] = 1 : channel 0 enabled
++                                                  bit[1] = 0 : channel 1 disabled
++                                                     [1] = 1 : channel 1 enabled
++                                                  bit[2] = 0 : channel 2 disabled
++                                                     [2] = 1 : channel 2 enabled
++                                                  bit[3] = 0 : channel 3 disabled
++                                                     [3] = 1 : channel 3 enabled */
++};
++
++
++typedef struct _PCM_OBJECT_    PCM_OBJECT_T;
++
++struct _PCM_OBJECT_
++{
++    u32          config_0;
++    u32          config_1; 
++    
++    u32          channel_0_config;
++    u32          channel_1_config;
++    u32          channel_2_config;
++    u32          channel_3_config;
++    
++    u32          interrupt_config;
++    
++    /* 
++     * For interrupt setting
++     */
++//    INTC_OBJECT_T    intc_obj;
++};
++
++
++
++/*
++ * function declarations
++ */
++void       Hal_Pcm_Initialize(PCM_OBJECT_T *);
++
++                                                                           
++/*
++ * macro declarations
++ */
++#define HAL_PCM_ENABLE_PCM() \
++{ \
++    (PCM_CONFIGURATION_0_REG) |= ((u32)0x1 << 31); \
++}
++
++#define HAL_PCM_DISABLE_PCM() \
++{ \
++    (PCM_CONFIGURATION_0_REG) &= ~((u32)0x1 << 31); \
++}
++
++#define HAL_PCM_ENABLE_DATA_SWAP() \
++{ \
++    (PCM_CONFIGURATION_0_REG) |= (0x1 << 24); \
++}
++
++#define HAL_PCM_DISABLE_DATA_SWAP() \
++{ \
++    (PCM_CONFIGURATION_0_REG) &= ~(0x1 << 24); \
++}
++
++#define HAL_PCM_WRITE_TX_DATA_0(tx_data_0) \
++{ \
++    (PCM_TX_DATA_31_0_REG) = tx_data_0; \
++}
++
++#define HAL_PCM_WRITE_TX_DATA_1(tx_data_1) \
++{ \
++    (PCM_TX_DATA_63_32_REG) = tx_data_1; \
++}
++
++#define HAL_PCM_READ_RX_DATA_0(rx_data_0) \
++{ \
++    (rx_data_0) = PCM_RX_DATA_31_0_REG; \
++}
++
++#define HAL_PCM_READ_RX_DATA_1(rx_data_1) \
++{ \
++    (rx_data_1) = PCM_RX_DATA_63_32_REG; \
++}
++
++#define HAL_PCM_READ_INTERRUPT_STATUS(status) \
++{ \
++    (status) = PCM_INTERRUPT_STATUS_REG; \
++}
++
++#define HAL_PCM_CLEAR_INTERRUPT_STATUS(status) \
++{ \
++    (PCM_INTERRUPT_STATUS_REG) = (status & 0xC0); \
++}
++
++#define HAL_PCM_DISABLE_RECEIVE_BUFFER_FULL_INTERRUPT() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_PCM_DISABLE_TRANSMIT_BUFFER_EMPTY_INTERRUPT() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_PCM_DISABLE_RECEIVE_BUFFER_OVERRUN_INTERRUPT() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) &= ~(0x1 << 2); \
++}
++
++#define HAL_PCM_DISABLE_TRANSMIT_BUFFER_UNDERRUN_INTERRUPT() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) &= ~(0x1 << 3); \
++}
++
++#define HAL_PCM_DISABLE_ALL_INTERRUPT_SOURCES() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) = 0; \
++}
++
++#endif  // end of #ifndef _STAR_PCM_H_
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_powermgt.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_powermgt.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_powermgt.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_powermgt.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,616 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_POWERMGT_H_
++#define	_STAR_POWERMGT_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	PWRMGT_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSPA_POWER_MANAGEMENT_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	PWRMGT_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSVA_POWER_MANAGEMENT_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	PWRMGT_CLOCK_GATE_CONTROL0_REG			PWRMGT_MEM_MAP_VALUE(0x00)
++#define	PWRMGT_CLOCK_GATE_CONTROL1_REG			PWRMGT_MEM_MAP_VALUE(0x04)
++#define	PWRMGT_SOFTWARE_RESET_CONTROL_REG		PWRMGT_MEM_MAP_VALUE(0x08)
++#define	PWRMGT_SYSTEM_CLOCK_CONTROL_REG			PWRMGT_MEM_MAP_VALUE(0x0C)
++#define	PWRMGT_PLL_POWER_DOWN_CONTROL_REG		PWRMGT_MEM_MAP_VALUE(0x10)
++#define	PWRMGT_CPU_INITIALIZATION_REG			PWRMGT_MEM_MAP_VALUE(0x14)
++#define	PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG		PWRMGT_MEM_MAP_VALUE(0x1C)
++#define	PWRMGT_USB_DEVICE_POWERMGT_REG			PWRMGT_MEM_MAP_VALUE(0x20)
++#define	PWRMGT_REGULATOR_CONTROL_REG			PWRMGT_MEM_MAP_VALUE(0x24)
++#define	PWRMGT_RTC_XTAL_CONTROL_REG			PWRMGT_MEM_MAP_VALUE(0x28)
++#define	PWRMGT_PLL250_CONTROL_REG			PWRMGT_MEM_MAP_VALUE(0x2C)
++
++
++/*
++ * define constants macros
++ */
++#define	PWRMGT_PCMCIA_SOFTWARE_RESET_BIT_INDEX			(1)
++#define	PWRMGT_IDE_SOFTWARE_RESET_BIT_INDEX			(2)
++#define	PWRMGT_VIC_SOFTWARE_RESET_BIT_INDEX			(3)
++#define	PWRMGT_DMA_SOFTWARE_RESET_BIT_INDEX			(4)
++#define	PWRMGT_NIC_SOFTWARE_RESET_BIT_INDEX			(5)
++#define	PWRMGT_USB_HOST_SOFTWARE_RESET_BIT_INDEX		(6)
++#define	PWRMGT_PCI_BRIDGE_SOFTWARE_RESET_BIT_INDEX		(7)
++#define	PWRMGT_P2S_SOFTWARE_RESET_BIT_INDEX			(8)
++#define	PWRMGT_UART0_SOFTWARE_RESET_BIT_INDEX			(9)
++#define	PWRMGT_UART1_SOFTWARE_RESET_BIT_INDEX			(10)
++#define	PWRMGT_TIMER_SOFTWARE_RESET_BIT_INDEX			(11)
++#define	PWRMGT_WDTIMER_SOFTWARE_RESET_BIT_INDEX			(12)
++#define	PWRMGT_GPIO_SOFTWARE_RESET_BIT_INDEX			(13)
++#define	PWRMGT_USB_DEVICE_SOFTWARE_RESET_BIT_INDEX		(14)
++#define	PWRMGT_FAST_ETHERNET_PHY_SOFTWARE_RESET_BIT_INDEX	(15)
++#define	PWRMGT_HSDMA_SOFTWARE_RESET_BIT_INDEX			(16)
++
++
++#define	PWRMGT_PLL_FREQUENCY_175MHZ			(0 << 0)
++#define	PWRMGT_PLL_FREQUENCY_200MHZ			(1 << 0)
++#define	PWRMGT_PLL_FREQUENCY_225MHZ			(2 << 0)
++#define	PWRMGT_PLL_FREQUENCY_250MHZ			(3 << 0)
++
++#define	PWRMGT_CPUCLK_DIVIDER_BY_1			(0 << 2)
++#define	PWRMGT_CPUCLK_DIVIDER_BY_2			(1 << 2)
++#define	PWRMGT_CPUCLK_DIVIDER_BY_3			(2 << 2)
++#define	PWRMGT_CPUCLK_DIVIDER_BY_4			(3 << 2)
++
++#define	PWRMGT_HCLK_DIVIDER_BY_1			(0 << 4)
++#define	PWRMGT_HCLK_DIVIDER_BY_2			(1 << 4)
++#define	PWRMGT_HCLK_DIVIDER_BY_3			(2 << 4)
++#define	PWRMGT_HCLK_DIVIDER_BY_4			(3 << 4)
++
++#define	PWRMGT_HCLK_SOURCE_FCLK				(0 << 6)
++#define	PWRMGT_HCLK_SOURCE_125MHZ			(1 << 6)
++
++#define	PWRMGT_PCLK_DIVIDER_BY_1			(0 << 8)
++#define	PWRMGT_PCLK_DIVIDER_BY_2			(1 << 8)
++#define	PWRMGT_PCLK_DIVIDER_BY_3			(2 << 8)
++#define	PWRMGT_PCLK_DIVIDER_BY_4			(3 << 8)
++
++#define	PWRMGT_PCICLK_DIVIDER_BY_1			(0 << 10)
++#define	PWRMGT_PCICLK_DIVIDER_BY_2			(1 << 10)
++#define	PWRMGT_PCICLK_DIVIDER_BY_3			(2 << 10)
++#define	PWRMGT_PCICLK_DIVIDER_BY_4			(3 << 10)
++
++
++#define	PWRMGT_PLLCLK_TO_CPUCLK_RATIO_BY_1		(1)
++#define	PWRMGT_PLLCLK_TO_CPUCLK_RATIO_BY_2		(2)
++#define	PWRMGT_PLLCLK_TO_CPUCLK_RATIO_BY_3		(3)
++#define	PWRMGT_PLLCLK_TO_CPUCLK_RATIO_BY_4		(4)
++
++#define	PWRMGT_CPUCLK_TO_HCLK_RATIO_BY_1		(1)
++#define	PWRMGT_CPUCLK_TO_HCLK_RATIO_BY_2		(2)
++#define	PWRMGT_CPUCLK_TO_HCLK_RATIO_BY_3		(3)
++#define	PWRMGT_CPUCLK_TO_HCLK_RATIO_BY_4		(4)
++
++#define	PWRMGT_HCLK_TO_PCLK_RATIO_BY_1			(1)
++#define	PWRMGT_HCLK_TO_PCLK_RATIO_BY_2			(2)
++#define	PWRMGT_HCLK_TO_PCLK_RATIO_BY_3			(3)
++#define	PWRMGT_HCLK_TO_PCLK_RATIO_BY_4			(4)
++
++/*
++ * Macro defines for Clock Gate	Control
++ */
++#define	HAL_PWRMGT_DISABLE_DRAMC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x1); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_NIC_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 0); \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x0F << 20); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 5); \
++}
++
++#define	HAL_PWRMGT_DISABLE_NIC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x0F <<	20); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_PCI_BRIDGE_33M_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 1); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	10); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 10); \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 28) | (0x1 << 30); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 7); \
++}
++
++#define	HAL_PWRMGT_ENABLE_PCI_BRIDGE_66M_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 1); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	10); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x0 << 10); \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 28) | (0x1 << 30); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 7); \
++}
++
++#define	HAL_PWRMGT_DISABLE_PCI_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~((0x1 <<	28) | (0x1 << 30)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_USB_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0xF << 1); \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 24); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 28); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 6) | (0x1 << 14); \
++}
++
++#define	HAL_PWRMGT_DISABLE_USB_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x1 << 24); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 28); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_DMA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 16); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 4); \
++}
++
++#define	HAL_PWRMGT_DISABLE_DMA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x1 << 16); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_IDE_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 8) | (0x1	<< 9); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 2); \
++}
++
++#define	HAL_PWRMGT_DISABLE_IDE_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~((0x1 <<	8) | (0x1 << 9)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_UART0_CLOCK()	\
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~((0x1	<< 1) |	(0x1 <<	2) | (0x1 << 5)); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 12); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 9); \
++}
++
++#define	HAL_PWRMGT_DISABLE_UART0_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 12); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_UART1_CLOCK()	\
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~((0x1	<< 1) |	(0x1 <<	2) | (0x1 << 5)); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 13); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 10); \
++}
++
++#define	HAL_PWRMGT_DISABLE_UART1_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 13); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_PCMCIA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 4) | (0x1	<< 5); \
++}
++
++#define	HAL_PWRMGT_DISABLE_PCMCIA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~((0x1 <<	4) | (0x1 << 5)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_GPIO_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 25); \
++}
++
++#define	HAL_PWRMGT_DISABLE_GPIO_CLOCK()	\
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 25); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_WDTIMER_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 21) | (0x1 << 22); \
++}
++
++#define	HAL_PWRMGT_DISABLE_WDTIMER_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	21) | (0x1 << 22)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_RTC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 23); \
++}
++
++#define	HAL_PWRMGT_DISABLE_RTC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 23); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_TIMER_CLOCK()	\
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 17) | (0x1 << 18)	| (0x1 << 19); \
++}
++
++#define	HAL_PWRMGT_DISABLE_TIMER_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	17) | (0x1 << 18) | (0x1 << 19)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_I2C_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 1); \
++}
++
++#define	HAL_PWRMGT_DISABLE_I2C_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 1); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_I2S_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~((0x1	<< 5) |	(0x1 <<	6)); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 1) | (0x1	<< 10);	\
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 8); \
++}
++
++#define	HAL_PWRMGT_DISABLE_I2S_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	1) | (0x1 << 10)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_PCM_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 5); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 1) | (0x1	<< 6); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 8); \
++}
++
++#define	HAL_PWRMGT_DISABLE_PCM_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	1) | (0x1 << 6)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_SPI_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 0) | (0x1	<< 1); \
++}
++
++#define	HAL_PWRMGT_DISABLE_SPI_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	0) | (0x1 << 1)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_VIC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 12); \
++}
++
++#define	HAL_PWRMGT_DISABLE_VIC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x1 << 12); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_SMC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 4) | (0x1	<< 5); \
++}
++
++#define	HAL_PWRMGT_DISABLE_SMC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~((0x1 <<	4) | (0x1 << 5)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_HSDMA_CLOCK()	\
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 29); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 16); \
++}
++
++#define	HAL_PWRMGT_DISABLE_HSDMA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 29); \
++}
++
++
++
++/*
++ * Macro defines for Reset Control
++ */
++#define	HAL_PWRMGT_GLOBAL_SOFTWARE_RESET() \
++{ \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1);	\
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1); \
++}
++
++
++/*
++ * Macro defines for System Clock Control
++ */
++#define	HAL_PWRMGT_SET_PLL_FREQUENCY_175MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~0x3; \
++}
++
++
++#define	HAL_PWRMGT_SET_PLL_FREQUENCY_200MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~0x3; \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= 0x1; \
++}
++
++
++#define	HAL_PWRMGT_SET_PLL_FREQUENCY_225MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~0x3; \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= 0x2; \
++}
++
++
++#define	HAL_PWRMGT_SET_PLL_FREQUENCY_250MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~0x3; \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= 0x3; \
++}
++
++
++#define	HAL_PWRMGT_CONFIG_PLLCLK_TO_CPUCLK_RATIO(ratio)	\
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	2); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (((ratio	- 1) & 0x3) << 2); \
++}
++
++
++#define	HAL_PWRMGT_CONFIG_CPUCLK_TO_HCLK_RATIO(ratio) \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	4); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (((ratio	- 1) & 0x3) << 4); \
++}
++
++
++#define	HAL_PWRMGT_HCLK_SOURCE_FCLK() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x1 <<	6); \
++}
++
++
++#define	HAL_PWRMGT_HCLK_SOURCE_125MHZ()	\
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 6); \
++}
++
++
++#define	HAL_PWRMGT_GIGA_NIC_CLOCK_SOURCE_HCLK()	\
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x1 <<	7); \
++}
++
++
++#define	HAL_PWRMGT_GIGA_NIC_CLOCK_SOURCE_62_5MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 7); \
++}
++
++
++#define	HAL_PWRMGT_CONFIG_HCLK_TO_PCLK_RATIO(ratio) \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	8); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (((ratio	- 1) & 0x3) << 8); \
++}
++
++
++#define	HAL_PWRMGT_I2S_CLOCK_SOURCE_8192000HZ()	\
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	12); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x0 << 12); \
++}
++
++
++#define	HAL_PWRMGT_I2S_CLOCK_SOURCE_11289600HZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	12); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 12); \
++}
++
++
++#define	HAL_PWRMGT_I2S_CLOCK_SOURCE_12288000HZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	12); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x2 << 12); \
++}
++
++
++#define	HAL_PWRMGT_CONFIGURE_MDC_CLOCK_DIVIDER(divided_value) \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	14); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= ((divided_value & 0x3) << 14); \
++}
++
++
++#define	HAL_PWRMGT_CONFIGURE_CLOCK_OUT_PIN(pin_source_select, divided_value) \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3F << 16); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= ((pin_source_select & 0xF) << 16); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= ((divided_value & 0x3) << 20); \
++}
++
++
++/*
++ * Macro defines for PLL Power Down Control
++ */
++#define	HAL_PWRMGT_POWER_DOWN_SYSTEM_XTAL_PAD()	\
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 7)
++
++#define	HAL_PWRMGT_POWER_ON_SYSTEM_XTAL_PAD() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 7)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X5() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 0)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X5() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 0)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X8() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 1)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X8() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 1)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X3() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 2)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X3() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 2)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_USBH_PHY_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 3)
++
++#define	HAL_PWRMGT_POWER_ON_USBH_PHY_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 3)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_USBD_PHY_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 4)
++
++#define	HAL_PWRMGT_POWER_ON_USBD_PHY_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 4)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X2250() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 5)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X2250()	\
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 5)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X7() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 6)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X7() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 6)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_ALL_PLL()	\
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG =	0x7F;
++
++#define	HAL_PWRMGT_POWER_ON_ALL_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG =	0;
++
++
++/*
++ * Macro defines for Pad Drive Strength	Control
++ */
++#define	HAL_PWRMGT_SELECT_PAD_DRIVE_STRENGTH_PCMCIA_CARDBUS_MODE() \
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG &= ~(0x3 << 0); \
++}
++
++#define	HAL_PWRMGT_SELECT_PAD_DRIVE_STRENGTH_PCI_MODE()	\
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG &= ~(0x3 << 0); \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG |= (0x1 << 0); \
++}
++
++#define	HAL_PWRMGT_SELECT_PAD_DRIVE_STRENGTH_MII_MODE()	\
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG |= (0x1 << 2); \
++}
++
++#define	HAL_PWRMGT_SELECT_PAD_DRIVE_STRENGTH_RGMII_MODE() \
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG &= ~(0x1 << 2); \
++}
++
++#define	HAL_PWRMGT_ENABLE_MII_PAD_SIGNAL_NOT_BOUNDED() \
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG |= (0x1 << 3); \
++}
++
++#define	HAL_PWRMGT_DISABLE_MII_PAD_SIGNAL_NOT_BOUNDED()	\
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG &= ~(0x1 << 3); \
++}
++
++
++/*
++ * Macro defines for USB Device	Power Management
++ */
++#define	HAL_PWRMGT_REMOTE_WAKEUP_USB_HOST() \
++{ \
++    PWRMGT_USB_DEVICE_POWERMGT_REG |= (0x1 << 4); \
++}
++
++#define	HAL_PWRMGT_USB_DEVICE_PHY_CLOCK_SOURCE_EXTERNAL_12MHZ()	\
++{ \
++    PWRMGT_USB_DEVICE_POWERMGT_REG &= ~(0x1 << 5); \
++}
++
++#define	HAL_PWRMGT_USB_DEVICE_PHY_CLOCK_SOURCE_INTERNAL_12MHZ()	\
++{ \
++    PWRMGT_USB_DEVICE_POWERMGT_REG |= (0x1 << 5); \
++}
++
++
++/*
++ * Macro defines for Regulator Control
++ */
++
++
++#endif	// end of #ifndef _STAR_POWERMGT_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_rtc.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_rtc.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_rtc.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_rtc.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,87 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_RTC_H_
++#define	_STAR_RTC_H_
++
++#include <mach/star_sys_memory_map.h>
++
++#define	RTC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_RTC_BASE_ADDR + reg_offset)))
++
++#define	RTC_SECOND_REG				RTC_MEM_MAP_VALUE(0x00)
++#define	RTC_MINUTE_REG				RTC_MEM_MAP_VALUE(0x04)
++#define	RTC_HOUR_REG				RTC_MEM_MAP_VALUE(0x08)
++#define	RTC_DAY_REG				RTC_MEM_MAP_VALUE(0x0C)
++#define	RTC_SECOND_ALARM_REG			RTC_MEM_MAP_VALUE(0x10)
++#define	RTC_MINUTE_ALARM_REG			RTC_MEM_MAP_VALUE(0x14)
++#define	RTC_HOUR_ALARM_REG			RTC_MEM_MAP_VALUE(0x18)
++#define	RTC_RECORD_REG				RTC_MEM_MAP_VALUE(0x1C)
++#define	RTC_CONTROL_REG				RTC_MEM_MAP_VALUE(0x20)
++#define	RTC_INTERRUPT_STATUS_REG		RTC_MEM_MAP_VALUE(0x34)
++
++#define	RTC_ENABLE_BIT				(1 << 0)
++#define	RTC_AUTO_SECOND_ALARM_ENABLE_BIT	(1 << 1)
++#define	RTC_AUTO_MINUTE_ALARM_ENABLE_BIT	(1 << 2)
++#define	RTC_AUTO_HOUR_ALARM_ENABLE_BIT		(1 << 3)
++#define	RTC_AUTO_DAY_ALARM_ENABLE_BIT		(1 << 4)
++#define	RTC_MATCH_ALARM_ENABLE_BIT		(1 << 5)
++#define	RTC_BATTERY_LOW_VOLTAGE_ENABLE_BIT	(1 << 6)
++
++#define RTC_AUTO_SECOND_ALARM_INTR_BIT      (1 << 0)
++#define RTC_AUTO_MINUTE_ALARM_INTR_BIT      (1 << 1)
++#define RTC_AUTO_HOUR_ALARM_INTR_BIT        (1 << 2)
++#define RTC_AUTO_DAY_ALARM_INTR_BIT         (1 << 3)
++#define RTC_MATCH_ALARM_INTR_BIT            (1 << 4)
++#define RTC_BATTERY_LOW_VOLTAGE_INTR_BIT    (1 << 5)
++
++#define	HAL_RTC_READ_SECOND(second)         ((second) = (RTC_SECOND_REG) & 0x3F);
++#define	HAL_RTC_READ_MINUTE(minute)         ((minute) = (RTC_MINUTE_REG) & 0x3F);
++#define	HAL_RTC_READ_HOUR(hour)	            ((hour) = (RTC_HOUR_REG) & 0x1F);
++#define	HAL_RTC_READ_DAY(day)               ((day) = (RTC_DAY_REG) & 0xFFFF);
++#define	HAL_RTC_ENABLE()                    ((RTC_CONTROL_REG) |= (RTC_ENABLE_BIT));
++#define	HAL_RTC_DISABLE()                   ((RTC_CONTROL_REG) &= ~(RTC_ENABLE_BIT));
++#define	HAL_RTC_AUTO_SECOND_ALARM_ENABLE()  ((RTC_CONTROL_REG) |= (RTC_AUTO_SECOND_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_SECOND_ALARM_DISABLE() ((RTC_CONTROL_REG) &= ~(RTC_AUTO_SECOND_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_MINUTE_ALARM_ENABLE()  ((RTC_CONTROL_REG) |= (RTC_AUTO_MINUTE_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_MINUTE_ALARM_DISABLE() ((RTC_CONTROL_REG) &= ~(RTC_AUTO_MINUTE_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_HOUR_ALARM_ENABLE()    ((RTC_CONTROL_REG) |= (RTC_AUTO_HOUR_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_HOUR_ALARM_DISABLE()   ((RTC_CONTROL_REG) &= ~(RTC_AUTO_HOUR_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_DAY_ALARM_ENABLE()	    ((RTC_CONTROL_REG) |= (RTC_AUTO_DAY_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_DAY_ALARM_DISABLE()    ((RTC_CONTROL_REG) &= ~(RTC_AUTO_DAY_ALARM_ENABLE_BIT));
++#define	HAL_RTC_MATCH_ALARM_ENABLE()        ((RTC_CONTROL_REG) |= (RTC_MATCH_ALARM_ENABLE_BIT));
++#define	HAL_RTC_MATCH_ALARM_DISABLE()       ((RTC_CONTROL_REG) &= ~(RTC_MATCH_ALARM_ENABLE_BIT));
++#define	HAL_RTC_BATTERY_LOW_VOLTAGE_INTERRUPT_ENABLE()   ((RTC_CONTROL_REG) |= (RTC_BATTERY_LOW_VOLTAGE_ENABLE_BIT));
++#define	HAL_RTC_BATTERY_LOW_VOLTAGE_INTERRUPT_DISABLE()	 ((RTC_CONTROL_REG) &= ~(RTC_BATTERY_LOW_VOLTAGE_ENABLE_BIT));
++#define	HAL_RTC_WRITE_RECORD(record)        ((RTC_RECORD_REG) =	(record));
++#define	HAL_RTC_READ_RECORD(record)         ((record) =	(RTC_RECORD_REG)); 
++#define	HAL_RTC_WRITE_MATCHED_ALARM_SECOND(second)  ((RTC_SECOND_ALARM_REG) = (second &	0x3F));
++#define	HAL_RTC_READ_MATCHED_ALARM_SECOND(second)   ((second) =	(RTC_SECOND_ALARM_REG) & 0x3F);
++#define	HAL_RTC_WRITE_MATCHED_ALARM_MINUTE(minute)  ((RTC_MINUTE_ALARM_REG) = (minute &	0x3F));
++#define	HAL_RTC_READ_MATCHED_ALARM_MINUTE(minute)   ((minute) =	(RTC_MINUTE_ALARM_REG) & 0x3F);
++#define	HAL_RTC_WRITE_MATCHED_ALARM_HOUR(hour)      ((RTC_HOUR_ALARM_REG) = (hour & 0x1F));
++#define	HAL_RTC_READ_MATCHED_ALARM_HOUR(hour)       ((hour) = (RTC_HOUR_ALARM_REG) & 0x1F);
++#define	HAL_RTC_READ_INTERRUPT_STATUS(status)       ((status) =	(RTC_INTERRUPT_STATUS_REG) & 0x3F);
++#define	HAL_RTC_WRITE_INTERRUPT_STATUS(status)      ((RTC_INTERRUPT_STATUS_REG)	= (status) & 0x3F);
++
++#endif
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_smc.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_smc.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_smc.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_smc.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,57 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_SMC_H_
++#define	_STAR_SMC_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	SMC_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSPA_SMC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	SMC_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSVA_SMC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++
++/*
++ * Static Memory Controller Registers
++ */
++#define	SMC_MEM_BANK0_CONFIG_REG	SMC_MEM_MAP_VALUE(0x00)
++#define	SMC_MEM_BANK0_TIMING_REG	SMC_MEM_MAP_VALUE(0x04)
++#define	SMC_MEM_BANK1_CONFIG_REG	SMC_MEM_MAP_VALUE(0x08)
++#define	SMC_MEM_BANK1_TIMING_REG	SMC_MEM_MAP_VALUE(0x0C)
++#define	SMC_MEM_BANK2_CONFIG_REG	SMC_MEM_MAP_VALUE(0x10)
++#define	SMC_MEM_BANK2_TIMING_REG	SMC_MEM_MAP_VALUE(0x14)
++#define	SMC_MEM_BANK3_CONFIG_REG	SMC_MEM_MAP_VALUE(0x18)
++#define	SMC_MEM_BANK3_TIMING_REG	SMC_MEM_MAP_VALUE(0x1C)
++
++/*
++ * macros declarations
++ */
++
++#endif	// end of #ifndef _STAR_SMC_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_spi.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_spi.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_spi.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_spi.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,169 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef _STAR_SPI_H_
++#define _STAR_SPI_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define SPI_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_SPI_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define SPI_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_SPI_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define SPI_CONFIGURATION_REG			SPI_MEM_MAP_VALUE(0x40)
++#define SPI_SERVICE_STATUS_REG			SPI_MEM_MAP_VALUE(0x44)
++#define SPI_BIT_RATE_CONTROL_REG		SPI_MEM_MAP_VALUE(0x48)
++#define SPI_TRANSMIT_CONTROL_REG		SPI_MEM_MAP_VALUE(0x4C)
++#define SPI_TRANSMIT_BUFFER_REG			SPI_MEM_MAP_VALUE(0x50)
++#define SPI_RECEIVE_CONTROL_REG			SPI_MEM_MAP_VALUE(0x54)
++#define SPI_RECEIVE_BUFFER_REG			SPI_MEM_MAP_VALUE(0x58)
++#define SPI_FIFO_TRANSMIT_CONFIG_REG		SPI_MEM_MAP_VALUE(0x5C)
++#define SPI_FIFO_TRANSMIT_CONTROL_REG		SPI_MEM_MAP_VALUE(0x60)
++#define SPI_FIFO_RECEIVE_CONFIG_REG		SPI_MEM_MAP_VALUE(0x64)
++#define SPI_INTERRUPT_STATUS_REG		SPI_MEM_MAP_VALUE(0x68)
++#define SPI_INTERRUPT_ENABLE_REG		SPI_MEM_MAP_VALUE(0x6C)
++
++
++/*
++ * define constants macros
++ */
++#define SPI_TX_RX_FIFO_DEPTH			(8)
++
++#define SPI_CH0					(0)
++#define SPI_CH1					(1)
++#define SPI_CH2					(2)
++#define SPI_CH3					(3)
++
++
++#define SPI_RXFIFO_OT_FG			(0x01)
++#define SPI_TXFIFO_UT_FG			(0x02)
++#define SPI_RXBUF_FULL_FG			(0x04)
++#define SPI_TXBUF_EMPTY_FG			(0x08)
++
++#define SPI_RXFIFO_OR_FG			(0x10)
++#define SPI_TXFIFO_UR_FG			(0x20)
++#define SPI_RXBUF_OR_FG				(0x40)
++#define SPI_TXBUF_UR_FG				(0x80)
++
++/*
++ * define Character Length Control
++ */
++#define SPI_LEN_BIT_8				(0)
++#define SPI_LEN_BIT_16				(1)
++#define SPI_LEN_BIT_24				(2)
++#define SPI_LEN_BIT_32				(3)
++
++
++/*
++ * macro declarations
++ */
++#define HAL_SPI_ENABLE_SPI() \
++{ \
++    (SPI_CONFIGURATION_REG) |= ((u_int32)0x1 << 31); \
++}
++
++#define HAL_SPI_DISABLE_SPI() \
++{ \
++    (SPI_CONFIGURATION_REG) &= ~((u_int32)0x1 << 31); \
++}
++
++#define HAL_SPI_ENABLE_DATA_SWAP() \
++{ \
++    (SPI_CONFIGURATION_REG) |= (0x1 << 24); \
++}
++
++#define HAL_SPI_DISABLE_DATA_SWAP() \
++{ \
++    (SPI_CONFIGURATION_REG) &= ~(0x1 << 24); \
++}
++
++#define HAL_SPI_TRANSMIT_DATA(tx_data) \
++{ \
++    (SPI_TRANSMIT_BUFFER_REG) = tx_data; \
++}
++
++#define HAL_SPI_RECEIVE_DATA(rx_data) \
++{ \
++    (rx_data) = SPI_RECEIVE_BUFFER_REG; \
++}
++
++#define HAL_SPI_GET_TRANSMIT_FIFO_WORDS_NUMBER(tx_fifo_words_num) \
++{ \
++    (tx_fifo_words_num) = SPI_FIFO_TRANSMIT_CONFIG_REG & 0xF; \
++}
++
++#define HAL_SPI_GET_RECEIVE_FIFO_WORDS_NUMBER(rx_fifo_words_num) \
++{ \
++    (rx_fifo_words_num) = SPI_FIFO_RECEIVE_CONFIG_REG & 0xF; \
++}
++
++#define HAL_SPI_DISABLE_ALL_INTERRUPT_SOURCES() \
++{ \
++    (SPI_INTERRUPT_ENABLE_REG) = 0; \
++}
++
++#define HAL_SPI_DISABLE_TX_FIFO_THRESHOLD_INTERRUPT() \
++{ \
++    (SPI_INTERRUPT_ENABLE_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_SPI_DISABLE_RX_FIFO_THRESHOLD_INTERRUPT() \
++{ \
++    (SPI_INTERRUPT_ENABLE_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_SPI_READ_INTERRUPT_STATUS(status) \
++{ \
++    (status) = SPI_INTERRUPT_STATUS_REG; \
++}
++
++#define HAL_SPI_CLEAR_INTERRUPT_STATUS(status) \
++{ \
++    (SPI_INTERRUPT_STATUS_REG) = (status & 0xF0); \
++}
++
++#define HAL_SPI_SET_FIFO_TRANSMIT_DELAY(delay) \
++{ \
++    (SPI_FIFO_TRANSMIT_CONTROL_REG) = (delay & 0x1F); \
++}
++
++#define STR8100_SPI_SERIAL_MODE_GENERAL              0x0
++#define STR8100_SPI_SERIAL_MODE_MICROPROCESSOR       0x1
++ 
++struct str8100_spi_dev_attr
++{ 
++	int spi_serial_mode;
++};
++
++#endif // end of #ifndef _STAR_SPI_H_
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_sys_memory_map.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_sys_memory_map.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_sys_memory_map.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_sys_memory_map.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,109 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_SYS_MEMORY_MAP_H_
++#define	_STAR_SYS_MEMORY_MAP_H_
++
++
++#if 0
++#define __UBOOT__
++#else
++#define __LINUX__
++#endif
++
++
++/*
++ * sytem memory	mapping	after reset
++ */
++#define SYSPA_FLASH_SRAM_BANK0_BASE_ADDR	0x10000000
++#define SYSPA_FLASH_SRAM_BANK1_BASE_ADDR	0x11000000
++#define SYSPA_FLASH_SRAM_BANK2_BASE_ADDR	0x12000000
++#define SYSPA_FLASH_SRAM_BANK3_BASE_ADDR	0x13000000
++#define	SYSPA_PCMCIA_ATTRIBUTE_MEMORY_BASE_ADDR	0x14000000
++#define	SYSPA_PCMCIA_COMMON_MEMORY_BASE_ADDR	0x15000000
++#define	SYSPA_PCMCIA_IO_SPACE_BASE_ADDR		0x16000000
++#define	SYSPA_IDE_DEVICE_BASE_ADDR		0x18000000
++#define	SYSPA_SDRAM_MEMORY_BASE_ADDR		0x20000000
++#define	SYSPA_GDMAC_BASE_ADDR			0x60000000
++#define	SYSPA_NIC_BASE_ADDR			0x70000000
++#define	SYSPA_SPI_BASE_ADDR			0x71000000
++#define	SYSPA_PCM_BASE_ADDR			0x71000000
++#define	SYSPA_I2C_BASE_ADDR			0x71000000
++#define	SYSPA_I2S_BASE_ADDR			0x71000000
++#define	SYSPA_DDRC_SDRC_BASE_ADDR		0x72000000
++#define	SYSPA_SMC_BASE_ADDR			0x73000000
++#define	SYSPA_PCMCIA_CONTROL_BASE_ADDR		0x73000000
++#define	SYSPA_IDE_CONTROLLER_BASE_ADDR		0x74000000
++#define	SYSPA_MISC_BASE_ADDR			0x76000000
++#define	SYSPA_POWER_MANAGEMENT_BASE_ADDR	0x77000000
++#define	SYSPA_UART0_BASE_ADDR			0x78000000
++#define	SYSPA_UART1_BASE_ADDR			0x78800000
++#define	SYSPA_TIMER_BASE_ADDR			0x79000000
++#define	SYSPA_WATCHDOG_TIMER_BASE_ADDR		0x7A000000
++#define	SYSPA_RTC_BASE_ADDR			0x7B000000
++#define	SYSPA_GPIOA_BASE_ADDR			0x7C000000
++#define	SYSPA_GPIOB_BASE_ADDR			0x7C800000
++#define	SYSPA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR	0xA0000000
++#define	SYSPA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR	0xA4000000
++#define	SYSPA_PCI_IO_SPACE_BASE_ADDR		0xA8000000
++#define	SYSPA_PCI_MEMORY_SPACE_BASE_ADDR	0xB0000000
++#define	SYSPA_USB11_CONFIG_BASE_ADDR		0xC0000000
++#define	SYSPA_USB11_OPERATION_BASE_ADDR		0xC4000000
++#define	SYSPA_USB20_CONFIG_BASE_ADDR		0xC8000000
++#define	SYSPA_USB20_OPERATION_BASE_ADDR		0xCC000000
++#define	SYSPA_USB20_DEVICE_BASE_ADDR		0xD0000000
++#define	SYSPA_VIC_BASE_ADDR			0xFFFFF000
++
++#if defined(__LINUX__)
++#define	SYSVA_FLASH_BASE_ADDR				0xFF000000
++#define SYSVA_IDE_DEVICE_BASE_ADDR		0xFFF00000
++#define SYSVA_GDMAC_BASE_ADDR			0xFFF01000
++#define SYSVA_NIC_BASE_ADDR			0xFFF02000
++#define SYSVA_SPI_BASE_ADDR			0xFFF03000
++#define SYSVA_PCM_BASE_ADDR			0xFFF04000
++#define SYSVA_I2C_BASE_ADDR			0xFFF05000
++#define SYSVA_I2S_BASE_ADDR			0xFFF06000
++#define SYSVA_DDRC_SDRC_BASE_ADDR		0xFFF07000
++#define SYSVA_SMC_BASE_ADDR			0xFFF08000
++#define SYSVA_PCMCIA_CONTROL_BASE_ADDR		0xFFF09000
++#define SYSVA_IDE_CONTROLLER_BASE_ADDR		0xFFF0A000
++#define SYSVA_MISC_BASE_ADDR			0xFFF0B000
++#define SYSVA_POWER_MANAGEMENT_BASE_ADDR	0xFFF0C000
++#define SYSVA_UART0_BASE_ADDR			0xFFF0D000
++#define SYSVA_UART1_BASE_ADDR			0xFFF0E000
++#define SYSVA_TIMER_BASE_ADDR			0xFFF0F000
++#define SYSVA_WATCHDOG_TIMER_BASE_ADDR		0xFFF10000
++#define SYSVA_RTC_BASE_ADDR			0xFFF11000
++#define SYSVA_GPIOA_BASE_ADDR			0xFFF12000
++#define SYSVA_GPIOB_BASE_ADDR			0xFFF13000
++#define SYSVA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR	0xFFF14000
++#define SYSVA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR	0xFFF15000
++#define SYSVA_USB11_CONFIG_BASE_ADDR		0xFFF16000
++#define SYSVA_USB11_OPERATION_BASE_ADDR		0xFFF17000
++#define SYSVA_USB20_CONFIG_BASE_ADDR		0xFFF18000
++#define SYSVA_USB20_OPERATION_BASE_ADDR		0xFFF19000
++#define SYSVA_USB20_DEVICE_BASE_ADDR		0xFFF1A000
++#define SYSVA_VIC_BASE_ADDR			0xFFF1B000
++#endif //__LINUX__
++
++#endif // end of #ifndef _STAR_SYS_MEMORY_MAP_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_timer.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_timer.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_timer.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_timer.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,312 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_TIMER_H_
++#define	_STAR_TIMER_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	TIMER_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_TIMER_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	TIMER_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_TIMER_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	TIMER1_COUNTER_REG			TIMER_MEM_MAP_VALUE(0x00)
++#define	TIMER1_AUTO_RELOAD_VALUE_REG		TIMER_MEM_MAP_VALUE(0x04)
++#define	TIMER1_MATCH_VALUE1_REG			TIMER_MEM_MAP_VALUE(0x08)
++#define	TIMER1_MATCH_VALUE2_REG			TIMER_MEM_MAP_VALUE(0x0C)
++
++#define	TIMER2_COUNTER_REG			TIMER_MEM_MAP_VALUE(0x10)
++#define	TIMER2_AUTO_RELOAD_VALUE_REG		TIMER_MEM_MAP_VALUE(0x14)
++#define	TIMER2_MATCH_VALUE1_REG			TIMER_MEM_MAP_VALUE(0x18)
++#define	TIMER2_MATCH_VALUE2_REG			TIMER_MEM_MAP_VALUE(0x1C)
++
++#define	TIMER1_TIMER2_CONTROL_REG		TIMER_MEM_MAP_VALUE(0x30)
++#define	TIMER1_TIMER2_INTERRUPT_STATUS_REG	TIMER_MEM_MAP_VALUE(0x34)
++#define	TIMER1_TIMER2_INTERRUPT_MASK_REG	TIMER_MEM_MAP_VALUE(0x38)
++
++#define	TIMER3_COUNTER_LOW_REG			TIMER_MEM_MAP_VALUE(0x40)
++#define	TIMER3_CONTROL_REG			TIMER_MEM_MAP_VALUE(0x44)
++
++
++/*
++ * define constants macros
++ */
++#define	TIMER1_ENABLE_BIT_INDEX			0
++#define	TIMER1_CLOCK_SOURCE_BIT_INDEX		1
++#define	TIMER1_OVERFLOW_ENABLE_BIT_INDEX	2
++
++#define	TIMER2_ENABLE_BIT_INDEX			3
++#define	TIMER2_CLOCK_SOURCE_BIT_INDEX		4
++#define	TIMER2_OVERFLOW_ENABLE_BIT_INDEX	5
++
++#define	TIMER1_UP_DOWN_COUNT_BIT_INDEX		9
++#define	TIMER2_UP_DOWN_COUNT_BIT_INDEX		10
++
++#define	TIMER1_MATCH1_INTERRUPT_BIT_INDEX	0
++#define	TIMER1_MATCH2_INTERRUPT_BIT_INDEX	1
++#define	TIMER1_OVERFLOW_INTERRUPT_BIT_INDEX	2
++
++#define	TIMER2_MATCH1_INTERRUPT_BIT_INDEX	3
++#define	TIMER2_MATCH2_INTERRUPT_BIT_INDEX	4
++#define	TIMER2_OVERFLOW_INTERRUPT_BIT_INDEX	5
++
++#define TIMER3_ENABLE_BIT_INDEX			17
++#define TIMER3_RESET_BIT_INDEX			16
++
++#define	TIMER_CLOCK_SOURCE_PCLK			0
++#define	TIMER_CLOCK_SOURCE_EXT_CLK		1
++
++
++#define	TIMER_OVERFLOW_MODE_DISABLE		0
++#define	TIMER_OVERFLOW_MODE_ENABLE		1
++
++
++#define	TIMER_COUNTER_MODE_UP			0
++#define	TIMER_COUNTER_MODE_DOWN			1
++
++
++#define	MATCH1_MASK_ENABLE			(1 << 0)
++
++#define	MATCH2_MASK_ENABLE			(1 << 1)
++
++#define	OVERFLOW_MASK_ENABLE			(1 << 2)
++
++
++/*
++ * macro declarations
++ */
++#define	HAL_TIMER_ENABLE_TIMER1() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER1_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER1() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER1_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_ENABLE_TIMER2() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER2_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER2() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER2_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_ENABLE_TIMER1_OVERFLOW_MODE()	\
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER1_OVERFLOW_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER1_OVERFLOW_MODE() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER1_OVERFLOW_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_ENABLE_TIMER2_OVERFLOW_MODE()	\
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER2_OVERFLOW_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER2_OVERFLOW_MODE() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER2_OVERFLOW_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_SET_TIMER1_DOWNCOUNT() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER1_UP_DOWN_COUNT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_SET_TIMER1_UPCOUNT() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER1_UP_DOWN_COUNT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_SET_TIMER2_DOWNCOUNT() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER2_UP_DOWN_COUNT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_SET_TIMER2_UPCOUNT() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER2_UP_DOWN_COUNT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_READ_INTERRUPT_STATUS(interrupt_status) \
++{ \
++    ((interrupt_status)	= (TIMER1_TIMER2_INTERRUPT_STATUS_REG)); \
++}
++
++
++#define	HAL_TIMER_WRITE_INTERRUPT_STATUS(interrupt_status) \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_STATUS_REG) = (interrupt_status)); \
++}
++
++
++#define	HAL_TIMER_READ_INTERRUPT_MASK(interrupt_mask) \
++{ \
++    ((interrupt_mask) =	(TIMER1_TIMER2_INTERRUPT_MASK_REG)); \
++}
++
++
++#define	HAL_TIMER_WRITE_INTERRUPT_MASK(interrupt_mask) \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	= (interrupt_mask)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER1_TIMER2_ALL_INTERRUPTS() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	= (0x3F));\
++}
++
++
++#define	HAL_TIMER_MASK_TIMER1_MATCH1_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER1_MATCH1_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER1_MATCH2_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER1_MATCH2_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER1_OVERFLOW_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER1_OVERFLOW_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER1_MATCH1_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER1_MATCH1_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER1_MATCH2_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER1_MATCH2_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER1_OVERFLOW_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER1_OVERFLOW_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER2_MATCH1_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER2_MATCH1_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER2_MATCH2_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER2_MATCH2_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER2_OVERFLOW_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER2_OVERFLOW_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER2_MATCH1_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER2_MATCH1_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER2_MATCH2_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER2_MATCH2_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER2_OVERFLOW_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER2_OVERFLOW_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER3() \
++{ \
++    ((TIMER3_CONTROL_REG) = 0); \
++}
++
++
++#define	HAL_TIMER_ENABLE_TIMER3() \
++{ \
++    ((TIMER3_CONTROL_REG) = (1 << TIMER3_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_RESET_TIMER3() \
++{ \
++    ((TIMER3_CONTROL_REG) = (1 << TIMER3_RESET_BIT_INDEX)); \
++}
++
++#ifndef __ASSEMBLY__
++static inline unsigned long long HAL_TIMER_GET_TIMER3_COUNTER(void)
++{
++	unsigned long h;
++	unsigned long l;
++
++	h = TIMER3_CONTROL_REG & 0xFFFF;
++	l = TIMER3_COUNTER_LOW_REG;
++
++	return ((((unsigned long long)h) << 32) | l);
++}
++#endif
++
++#endif	// end of #ifndef _STAR_TIMER_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_uart.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_uart.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_uart.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_uart.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,350 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_UART_H_
++#define	_STAR_UART_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#define	UART_MEM_MAP_VALUE_PHY(reg_offset)	(*((u32	volatile *)(SYSPA_UART0_BASE_ADDR + reg_offset)))
++#define	UART_MEM_MAP_VALUE_VIR(reg_offset)	(*((u32	volatile *)(SYSVA_UART0_BASE_ADDR + reg_offset)))
++
++
++#define	UART1_OFFSET		0x800000  //SYS_UART1_BASE_ADDR	= 0x78800000 = (UART1_OFFSET+ SYS_UART0_BASE_ADDR)
++
++#define	__UART_RBR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++#define	__UART_THR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++#define	__UART_DLL(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++
++#define	__UART_IER(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x04)
++#define	__UART_DLM(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x04)
++
++#define	__UART_IIR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++#define	__UART_FCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++#define	__UART_PSR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++
++#define	__UART_LCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x0C)
++#define	__UART_MCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x10) //UART(n) Control Reg
++#define	__UART_LSR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x14)
++#define	__UART_SPR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x1C)
++
++#if defined(__UBOOT__)
++#define	_UART_RBR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++#define	_UART_THR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++#define	_UART_DLL(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++
++#define	_UART_IER(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x04)
++#define	_UART_DLM(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x04)
++
++#define	_UART_IIR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++#define	_UART_FCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++#define	_UART_PSR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++
++#define	_UART_LCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x0C)
++#define	_UART_MCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x10) //UART(n) Control Reg
++#define	_UART_LSR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x14)
++#define	_UART_SPR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x1C)
++#elif defined(__LINUX__)
++#define	_UART_RBR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x00)
++#define	_UART_THR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x00)
++#define	_UART_DLL(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x00)
++
++#define	_UART_IER(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x04)
++#define	_UART_DLM(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x04)
++
++#define	_UART_IIR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x08)
++#define	_UART_FCR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x08)
++#define	_UART_PSR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x08)
++
++#define	_UART_LCR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x0C)
++#define	_UART_MCR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x10) //UART(n) Control Reg
++#define	_UART_LSR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x14)
++#define	_UART_SPR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x1C)
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define constants macros
++ */
++#define	UART_INPUT_CLOCK		(13000000)
++
++
++#define	UART_FIFO_DEPTH			16
++
++
++#define	RX_DATA_READY_INT		(1 << 0)
++#define	THR_EMPTY_INT			(1 << 1)
++#define	RX_LINE_STATUS_INT		(1 << 2)
++#define	MODEM_STATUS_INT		(1 << 3)
++
++
++#define	NO_INT_PENDING_MASK		(0x1)
++#define	RX_LINE_STATUS_INT_MASK		(0x6)
++#define	RX_DATA_READY_INT_MASK		(0x4)
++#define	RX_DATA_TIMEOUT_INT_MASK	(0xC)
++#define	THR_EMPTY_INT_MASK		(0x2)
++#define	MODEM_STATUS_CHANGE_MASK	(0x0)
++
++
++/* FCR Register	*/
++#define	FIFO_ENABLE			(1 << 0)
++#define	RX_FIFO_RESET			(1 << 1)
++#define	TX_FIFO_RESET			(1 << 2)
++#define	DMA_MODE			(1 << 3)
++
++
++#define	RX_FIFO_TRIGGER_LEVEL_1		(0 << 6)
++#define	RX_FIFO_TRIGGER_LEVEL_4		(1 << 6)
++#define	RX_FIFO_TRIGGER_LEVEL_8		(2 << 6)
++#define	RX_FIFO_TRIGGER_LEVEL_14	(3 << 6)
++
++
++#define	TX_FIFO_TRIGGER_LEVEL_1		(0 << 4)
++#define	TX_FIFO_TRIGGER_LEVEL_3		(1 << 4)
++#define	TX_FIFO_TRIGGER_LEVEL_9		(2 << 4)
++#define	TX_FIFO_TRIGGER_LEVEL_13	(3 << 4)
++
++
++
++/* LCR Register	*/
++#define	WORD_LENGTH_5			(0 << 0)
++#define	WORD_LENGTH_6			(1 << 0)
++#define	WORD_LENGTH_7			(2 << 0)
++#define	WORD_LENGTH_8			(3 << 0)
++
++#define	STOP_BIT_1			(0 << 2)
++#define	STOP_BIT_1_5			(1 << 2)
++#define	STOP_BIT_2			(1 << 2)
++
++#define	PARITY_CHECK_NONE		(0 << 3)
++#define	PARITY_CHECK_EVEN		(3 << 3)
++#define	PARITY_CHECK_ODD		(1 << 3)
++#define	PARITY_CHECK_STICK_ONE		(5 << 3)
++#define	PARITY_CHECK_STICK_ZERO		(7 << 3)
++
++#define	SET_BREAK			(1 << 6)
++
++#define	DLAB_ENABLE			(1 << 7)
++
++/* MCR Register	*/
++//#define UART_MCR_DTR			0x1		/* Data	Terminal Ready */
++//#define UART_MCR_RTS			0x2		/* Request to Send */
++//#define UART_MCR_OUT1			0x4		/* output1 */
++//#define UART_MCR_OUT2			0x8		/* output2 or global interrupt enable */
++#define	UART_MCR_LPBK			0x10		/* loopback mode */
++
++
++/* LSR Register	*/
++#define	_DATA_READY			(1 << 0)
++#define	OVERRUN_ERROR			(1 << 1)
++#define	PARITY_ERROR			(1 << 2)
++#define	FRAMING_ERROR			(1 << 3)
++#define	BREAK_INTERRUPT			(1 << 4)
++#define	THR_EMPTY			(1 << 5)
++#define	TRANSMITTER_EMPTY		(1 << 6)
++#define	FIFO_DATA_ERROR			(1 << 7)
++
++#define	TEST_PARITY_ERROR		(1 << 0)
++#define	TEST_FRAMING_ERROR		(1 << 1)
++#define	TEST_BAUD_GEN			(1 << 2)
++#define	TEST_LOOPBACK_ENABLE		(1 << 3)
++
++
++#define	WORD_FIVE_BITS			5
++#define	WORD_SIX_BITS			6
++#define	WORD_SEVEN_BITS			7
++#define	WORD_EIGHT_BITS			8
++
++#define	NONE_PARITY			1
++#define	EVEN_PARITY			2
++#define	ODD_PARITY			3
++#define	ONE_PARITY			4
++#define	ZERO_PARITY			5
++
++#define	ONE_STOP_BIT			1
++#define	ONE_HALF_STOP_BIT		2
++#define	TWO_STOP_BIT			3
++
++#define	TX_RX_FIFO_DISABLE		0
++#define	TX_RX_FIFO_ENABLE		1
++
++
++/*
++ * macros declarations
++ */
++
++#define	HAL_UART_READ_DATA(idx,data) \
++{ \
++    ((data) = (_UART_RBR(idx)) & 0xFF);	\
++}
++
++
++#define	HAL_UART_WRITE_DATA(idx,data) \
++{ \
++    ((_UART_THR(idx)) =	(data) & 0xFF);	\
++}
++
++
++#define	HAL_UART_ENABLE_INTERRUPT_TYPE(idx,interrupt_type) \
++{ \
++    ((_UART_IER(idx)) |= (interrupt_type & 0xF)); \
++}
++
++
++#define	HAL_UART_DISABLE_INTERRUPT_TYPE(idx,interrupt_type) \
++{ \
++    ((_UART_IER(idx)) &= ~(interrupt_type & 0xF)); \
++}
++
++
++#define	HAL_UART_READ_INTERRUPT_IDENTIFICATION(idx,uart_IIR) \
++{ \
++    ((uart_IIR)	= (_UART_IIR(idx))); \
++}
++
++
++#define	HAL_UART_CHECK_NO_INT_PENDING(idx,uart_IIR) \
++{ \
++    (((uart_IIR) & 0xF)	== (NO_INT_PENDING_MASK)); \
++}
++
++
++#define	HAL_UART_CHECK_RX_LINE_STATUS_INT(idx,uart_IIR)	\
++    (((uart_IIR) & 0xF)	== (RX_LINE_STATUS_INT_MASK))
++
++
++#define	HAL_UART_CHECK_RX_DATA_READY_INT(idx,uart_IIR) \
++    (((uart_IIR) & 0xF)	== (RX_DATA_READY_INT_MASK))
++
++
++#define	HAL_UART_CHECK_RX_DATA_TIMEOUT_INT(idx,uart_IIR) \
++    (((uart_IIR) & 0xF)	== (RX_DATA_TIMEOUT_INT_MASK))
++
++
++#define	HAL_UART_CHECK_THR_EMPTY_INT(idx,uart_IIR) \
++    (((uart_IIR) & 0xF)	== (THR_EMPTY_INT_MASK))
++
++
++#define	HAL_UART_FIFO_ENABLE(idx) \
++{ \
++    ((_UART_FCR(idx)) |= (FIFO_ENABLE)); \
++}
++
++
++#define	HAL_UART_FIFO_DISABLE(idx) \
++{ \
++    ((_UART_FCR(idx)) &= ~(FIFO_ENABLE)); \
++}
++
++
++#define	HAL_UART_RESET_RX_FIFO(idx) \
++{ \
++   ((_UART_FCR(idx)) |=	(RX_FIFO_RESET)); \
++}
++
++
++#define	HAL_UART_RESET_TX_FIFO(idx) \
++{ \
++    ((_UART_FCR(idx)) |= (TX_FIFO_RESET)); \
++}
++
++
++#define	HAL_UART_DLAB_ENABLE(idx) \
++{ \
++    ((_UART_LCR(idx)) |= (DLAB_ENABLE)); \
++}
++
++
++#define	HAL_UART_DLAB_DISABLE(idx) \
++{ \
++    ((_UART_LCR(idx)) &= ~(DLAB_ENABLE)); \
++}
++
++
++#define	HAL_UART_ENABLE_LOOPBACK_MODE(idx) \
++{ \
++    ((_UART_MCR(idx)) |= (UART_MCR_LPBK)); \
++}
++
++
++#define	HAL_UART_DISABLE_LOOPBACK_MODE(idx) \
++{ \
++    ((_UART_MCR(idx)) &= ~(UART_MCR_LPBK)); \
++}
++
++
++#define	HAL_UART_READ_LINE_STATUS(idx,uart_LSR)	\
++{ \
++    ((uart_LSR)	= (_UART_LSR(idx))); \
++}
++
++
++#define	HAL_UART_WRITE_DLL(idx,dll_value) \
++{ \
++    HAL_UART_DLAB_ENABLE(idx); \
++    _UART_DLL(idx) = (u32)dll_value; \
++    HAL_UART_DLAB_DISABLE(idx);	\
++}
++
++
++#define	HAL_UART_WRITE_DLM(idx,dlm_value) \
++{ \
++    HAL_UART_DLAB_ENABLE(idx); \
++    _UART_DLM(idx) = (u32)dlm_value; \
++    HAL_UART_DLAB_DISABLE(idx);	\
++}
++
++
++#define	HAL_UART_WRITE_PSR(idx,psr_value) \
++{ \
++    HAL_UART_DLAB_ENABLE(idx); \
++    _UART_PSR(idx) = (u32)(psr_value & 0x3); \
++    HAL_UART_DLAB_DISABLE(idx);	\
++}
++
++
++#define	HAL_UART_READ_PSR(idx,psr_value) \
++{ \
++    HAL_UART_DLAB_ENABLE(idx); \
++    (psr_value)	= (u32)((_UART_PSR(idx)) & 0x3); \
++    HAL_UART_DLAB_DISABLE(idx);	\
++}
++
++
++#define	HAL_UART_CHECK_RX_DATA_READY(idx) \
++    (((_UART_LSR(idx)) & _DATA_READY) == (_DATA_READY))
++
++
++#define	HAL_UART_CHECK_TX_FIFO_EMPTY(idx) \
++    (((_UART_LSR(idx)) & THR_EMPTY) == (THR_EMPTY))
++
++
++#define	HAL_UART_CHECK_TRANSMITTER_EMPTY(idx) \
++    (((_UART_LSR(idx)) & TRANSMITTER_EMPTY) == (TRANSMITTER_EMPTY))
++
++
++#endif	// end of #ifndef _STAR_UART_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_wdtimer.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_wdtimer.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_wdtimer.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_wdtimer.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,170 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_WATCHDOG_TIMER_H_
++#define	_STAR_WATCHDOG_TIMER_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	WDTIMER_MEM_MAP_VALUE(reg_offset)	(*((u32	volatile *)(SYSPA_WATCHDOG_TIMER_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	WDTIMER_MEM_MAP_VALUE(reg_offset)	(*((u32	volatile *)(SYSVA_WATCHDOG_TIMER_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	WDTIMER_COUNTER_REG			WDTIMER_MEM_MAP_VALUE(0x00)
++#define	WDTIMER_AUTO_RELOAD_REG			WDTIMER_MEM_MAP_VALUE(0x04)
++#define	WDTIMER_COUNTER_RESTART_REG		WDTIMER_MEM_MAP_VALUE(0x08)
++#define	WDTIMER_CONTROL_REG			WDTIMER_MEM_MAP_VALUE(0x0C)
++#define	WDTIMER_STATUS_REG			WDTIMER_MEM_MAP_VALUE(0x10)
++#define	WDTIMER_CLEAR_REG			WDTIMER_MEM_MAP_VALUE(0x14)
++#define	WDTIMER_INTERRUPT_LENGTH_REG		WDTIMER_MEM_MAP_VALUE(0x18)
++
++
++/*
++ * define constants macros
++ */
++#define	WDTIMER_ENABLE_BIT			(1 << 0)
++#define	WDTIMER_SYSTEM_RESET_ENABLE_BIT		(1 << 1)
++#define	WDTIMER_SYSTEM_INTERRUPT_ENABLE_BIT	(1 << 2)
++#define	WDTIMER_EXTERNAL_SIGNAL_ENABLE_BIT	(1 << 3)
++#define	WDTIMER_EXTERNAL_CLOCK_ENABLE_BIT	(1 << 4)
++
++
++#define	WDTIMER_MAGIC_RESTART_VALUE		(0x5AB9)
++
++
++/*
++ * macros declarations
++ */
++#define	HAL_WDTIMER_READ_COUNTER(counter) \
++{ \
++    ((counter) = (WDTIMER_COUNTER_REG)); \
++}
++
++
++#define	HAL_WDTIMER_WRITE_AUTO_RELOAD_COUNTER(counter) \
++{ \
++    ((WDTIMER_AUTO_RELOAD_REG) = (counter)); \
++}
++
++
++#define	HAL_WDTIMER_READ_AUTO_RELOAD_COUNTER(counter) \
++{ \
++    ((counter) = (WDTIMER_AUTO_RELOAD_REG)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE_RESTART_RELOAD() \
++{ \
++    ((WDTIMER_COUNTER_RESTART_REG) = (WDTIMER_MAGIC_RESTART_VALUE)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_DISABLE() \
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE_SYSTEM_RESET() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_SYSTEM_RESET_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_DISABLE_SYSTEM_RESET() \
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_SYSTEM_RESET_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE_SYSTEM_INTERRUPT() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_SYSTEM_INTERRUPT_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_DISABLE_SYSTEM_INTERRUPT() \
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_SYSTEM_INTERRUPT_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE_EXTERNAL_SIGNAL() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_EXTERNAL_SIGNAL_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_DISABLE_EXTERNAL_SIGNAL() \
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_EXTERNAL_SIGNAL_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_CLOCK_SOURCE_PCLK()	\
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_EXTERNAL_CLOCK_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_CLOCK_SOURCE_EXTCLK() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_EXTERNAL_CLOCK_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_READ_STATUS(status)	\
++{ \
++    ((status) =	(WDTIMER_STATUS_REG) & 0x00000001); \
++}
++
++
++#define	HAL_WDTIMER_CLEAR_STATUS() \
++{ \
++    ((WDTIMER_CLEAR_REG) = (1)); \
++}
++
++
++#define	HAL_WDTIMER_WRITE_INTERRUPT_LENGTH(length) \
++{ \
++    ((WDTIMER_INTERRUPT_LENGTH_REG) = (length) & 0x000000FF); \
++}
++
++
++#endif	// end of #ifndef _STAR_WATCHDOG_TIMER_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/system.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/system.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/system.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,50 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_SYSTEM_H__
++#define __ASM_ARCH_SYSTEM_H__
++
++#include <mach/star_powermgt.h>
++#include <mach/star_timer.h>
++
++static inline void arch_idle(void)
++{
++	volatile u32 dst= (*((u32 volatile *)(SYSVA_FLASH_BASE_ADDR + 0x20000)));
++
++// local_irq_enable();
++
++	cpu_do_idle();
++}
++
++static inline void arch_reset(char mode, const char *cmd)
++{
++	HAL_PWRMGT_GLOBAL_SOFTWARE_RESET();
++}
++
++extern u64 volatile str8100_counter_tick;
++static inline u64 str8100_read_counter(void)
++{
++        return (str8100_counter_tick + TIMER2_COUNTER_REG);
++}
++
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/timex.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/timex.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/timex.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,33 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_TIMEX_H__
++#define __ASM_ARCH_TIMEX_H__
++
++#if 1 // on ASIC
++#define CLOCK_TICK_RATE		(43750000)
++#else // on FPGA
++#define CLOCK_TICK_RATE		(13000000)
++#endif
++
++#endif /* __ASM_ARCH_TIMEX_H__ */
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/uncompress.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/uncompress.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/uncompress.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,87 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_UNCOMPRESS_H__
++#define __ASM_ARCH_UNCOMPRESS_H__
++
++#include <mach/star_uart.h>
++
++#define flush(x)	
++
++
++static void putstr(const char *s)
++{
++	while (*s) {
++		volatile unsigned int status = 0;
++
++		do {
++			status = __UART_LSR(0);
++		} while (!((status & THR_EMPTY) == THR_EMPTY));
++
++		__UART_THR(0) = *s;
++
++		if (*s == '\n') {
++			do {
++				status = __UART_LSR(0);
++			} while (!((status & THR_EMPTY) == THR_EMPTY));
++			__UART_THR(0) = '\r';
++		}
++		s++;
++	}
++}
++
++static const char * const digits="0123456789ABCDEF";
++static void ser_puts_hex8(unsigned char hex)
++{ 
++   char buf[3];
++   buf[0] = digits[(hex >> 4) & 0xF];
++   buf[1] = digits[hex & 0xF];
++      
++   buf[2] = '\0';
++   putstr(buf);
++}
++void ser_puts_hex32(unsigned long hex)
++{
++   char buf[9];
++   int i;
++   
++   for(i=7; i >= 0; i--)
++   {
++      buf[7-i] = digits[(hex >> (i * 4)) & 0xF];
++   }
++   
++   buf[8] = '\0';
++  putstr(buf);
++}
++
++/*
++static void putc(int c)
++{
++ star_putstr(&c);
++}
++
++*/
++#define arch_decomp_setup()
++#define arch_decomp_wdog()
++
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/vmalloc.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/vmalloc.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/vmalloc.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,31 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_VMALLOC_H__
++#define __ASM_ARCH_VMALLOC_H__
++
++//#include <linux/config.h>
++
++#define VMALLOC_END	(PAGE_OFFSET + 0x10000000)
++
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/Kconfig linux-2.6.35.11-ts7500/arch/arm/mach-str8100/Kconfig
+--- linux-2.6.35.11/arch/arm/mach-str8100/Kconfig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,143 @@
++if ARCH_STR8100
++
++menu "STR8100 Options"
++
++config CONSOLE_BAUD_RATE
++	int "Console Baud Rate"
++	default 38400
++	help
++	  set the console baudrate
++
++config VIC_INTERRUPT
++	bool "Enable Vector Interrupt Controller"
++	default y
++	help
++	  enable the vector interrupt controller
++
++choice
++	prompt "DRAM SIZE"
++	default STR8100_DRAM_16M
++
++config STR8100_DRAM_16M
++	bool "16MBytes"
++
++config STR8100_DRAM_32M
++	bool "32MBytes"
++
++config STR8100_DRAM_64M
++	bool "64MBytes"
++
++endchoice
++
++if PCI
++choice
++	prompt "PCI Frequency"
++	default STR8100_PCI33M
++
++config STR8100_PCI33M
++	bool "PCI_33Mhz"
++
++config STR8100_PCI66M
++	bool "PCI_66Mhz"
++
++endchoice
++endif
++
++config STR8100_DMA
++	bool "Enable DMA Controller"
++	default n
++	help
++	  enable the DMA controller
++
++config STR8100_HSDMA
++	bool "Enable HSDMA Controller"
++	default n
++	help
++	  enable the HSDMA controller
++
++config STR8100_INFO
++	bool "STR8100 Infomation at /proc/str8100/info"
++
++config STR8100_USBD_REBOOT_INTHANDLER
++	tristate "USB Mass Storage Device"
++
++config STR8100_I2S
++	bool "Enable I2S sound"
++	default n
++	help
++	  enable the I2S sound with /proc/str8100/i2s
++
++config STR8100_I2S_DEMO
++	tristate "Enable I2S sound demo driver"
++	default n
++	help
++	  enable the I2S sound demo driver with /proc/str8100/i2s
++
++config STR8100_I2S_WM8772_DEMO
++	tristate "Enable I2S sound demo driver with WM8772"
++	default n
++	help
++	  enable the I2S sound demo driver with wm8772
++
++config LE88221_CONTROL
++	bool "Legerity LE88221 Control Support"
++	depends on SPI
++
++config STR8100_PCM_LEGERITY_2PHONE_DEMO
++	tristate "2 phone PCM sound demo driver for Legerity"
++	select LE88221_CONTROL
++	default n
++
++config STR8100_RTC
++	bool "STR8100 Real Time Clock Support"
++
++config STR8100_GPIO
++	bool "STR8100 GPIO Support"
++	
++config STR8100_GPIO_INTERRUPT
++	bool "Interrupt Library Support"
++	depends on STR8100_GPIO	
++
++config STR8100_GPIO_GENERIC_INTERFACE
++	bool "Generic GPIO Interface Support"
++	depends on STR8100_GPIO	
++	select GENERIC_GPIO
++
++comment "Flash MAP"
++config STR8100_FLASH_PART
++	bool "STR8100 flash partition setting"
++
++if STR8100_FLASH_PART
++	config ARMBOOT_OFFSET
++	hex "ARMBOOT OFFSET"
++	default 0x0
++	help
++	  The armboot start offset in flash layout
++
++	config KERNEL_OFFSET
++	hex "KERNEL OFFSET"
++	default 0x40000
++	help
++	  The kernel start offset in flash layout
++
++	config ROOTFS_OFFSET
++	hex "ROOTFS OFFSET"
++	default 0x140000
++	help
++	  The rootfs start offset in flash layout
++
++	config CFG_OFFSET
++	hex "CFG OFFSET"
++	default 0x7f0000
++	help
++	  The cfg start offset in flash layout
++endif
++
++
++comment "Third Party Support"
++
++config STR8100_EWC_SUPPORT
++	bool "EWC(802.11N) Support"
++endmenu
++
++endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/le88221_control.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/le88221_control.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/le88221_control.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/le88221_control.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,1037 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/interrupt.h>
++#include <linux/spi/spi.h>
++#include <linux/delay.h>
++#include <asm/semaphore.h>
++#include <mach/star_spi.h>
++
++static struct spi_device *le88221_spidev;
++static struct semaphore le88221_lock;
++
++/******************************************************************************
++* Busy Tone
++* Frequency: 480Hz + 620Hz
++* Temporal Pattern: 0.5s on/ 0.5s off
++* Event Reported After: 2 cycles of precise, 3 cycles of nonprecise
++*******************************************************************************/
++void le88221_busy_tone(struct spi_device *spi)
++{
++	u8 rx_data;
++	u8 write_data;
++	int retval;
++
++	//enable channel 1 and channel 2
++	write_data = 0x4A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x03;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator 
++	//0x00: all disabled
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator C and D    
++	// 05 1F 1C C5 06 9D 1C C5
++	//FreqC= 1311(0x051f) * 0.3662 = 480.0882 Hz
++	//AmpC = 7365(0x1cc5) * 
++	//FreqD= 1693(0x069d) * 0.3662 = 619.9766 Hz
++	//AmpCD= 7365(0x1cc5) *
++	write_data = 0xD4;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x05;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x1F;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x1C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xC5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x06;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x9D;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x1C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xC5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Cadence Timer
++	// 00 64 00 64 (100ms On/ 100ms Off)
++	write_data = 0xE0;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x64;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x64;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator
++	//Eanble Signal generator cadencing, Signal generator C,D
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x8C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set System State
++	//Activate codec, Active Low battery
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x23;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++}
++
++/******************************************************************************
++* Dial Tone
++* Frequency: 350Hz + 440Hz
++* Temporal Pattern: Steady tone
++* Event Reported After: Approximately 0.75 seconds
++*******************************************************************************/
++void spi_le88221_dial_tone(struct spi_device *spi)
++{
++	u8 rx_data;
++	u8 write_data;
++	int retval;
++
++	//enable channel 1 and channel 2
++	write_data = 0x4A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x03;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator 
++	//0x00: all disabled
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator C and D    
++	// 03 BC 1C C5 04 B2 1C C5
++	write_data = 0xD4;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x03;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xBC;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x1C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xC5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x04;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xB2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x1C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xC5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Cadence Timer
++	// 00 00 00 00
++	write_data = 0xE0;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator
++	//Eanble Signal generator cadencing, Signal generator C,D
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x8C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set System State
++	//Activate codec, Active Low battery
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x23;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++}
++
++void le88221_balanced_ring(struct spi_device *spi)
++{
++	u8 rx_data;
++	u8 write_data;
++	int retval;
++ 
++	//enable channel 1 and channel 2
++	write_data = 0x4A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x03;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator
++	//0x00: all disabled
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Write Signal Generator A,B and Bias Param
++	// 00 00 00 00 37 42 5B 00 00 00 00
++	//0x00:Ramp has a positive slope, SG A,B out continuous, sinusoidal waves
++	//Bias : 0 (0x0000) V
++	//FreqA: 55(0x0037) * 0.3662 = 20.141 Hz 
++	//AmpA : 16987(0x425B)
++	//FreqB: 0(0x0000) * 0.3662 = 0 Hz
++	//AmpB : 0(0x0000)
++	write_data = 0xD2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x37;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x42;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x5B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set System State
++	//Activate codec, Active Mid Battery
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x2B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Loop Supervision Param
++	// 1B 84 B3 05
++	write_data = 0xC2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x1B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x84;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xB3;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x05;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set System state        
++	//Deactivate codec, Balanced ringing
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x07;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++}
++
++void le88221_unbalanced_ring(struct spi_device *spi)
++{
++	u8 rx_data;
++	u8 write_data;
++	int retval;
++
++	//enable channel 1 and channel 2
++	write_data = 0x4A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x03;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator 
++	//0x00: all disabled
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Cadence Timer
++	//01 90 03 20 (400ms on/800ms off)
++	write_data = 0xE0;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x01;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x90;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x03;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x20;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator 
++	// Enable tone generator specified by EGA...
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x80;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Write Signal Generator A,B and Bias Param
++	// 00 00 00 00 37 21 2D 00 00 00 00
++	//0x00:Ramp has a positive slope, SG A,B out continuous, sinusoidal waves
++	//Bias : 0(0x0000) V
++	//FreqA: 55(0x0037) * 0.3662 = 20.141 Hz 
++	//AmpA : 8493(0x212D)
++	//FreqB: 0(0x0000) * 0.3662 = 0 Hz
++	//AmpB : 0(0x0000)
++	write_data = 0xD2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x37;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x21;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x2D;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set System State
++	//Activate codec, Active Mid Battery
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x2B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Loop Supervision Param
++	// 1B 84 33 05
++	write_data = 0xC2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x1B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x84;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x33;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x05;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set System state        
++	//Deactivate codec, Balanced ringing
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x0A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++}
++
++u32 le88221_hook_off(struct spi_device *spi)
++{
++	u8 rx_data;
++	u8 rx_data21, rx_data22;
++	u8 write_data;
++	int retval;
++
++	/* if Hook1/2 off hook status at the same time */ 	        	    
++	/*
++	 * Check Hook1/2 On or Off (Read Signaling Register)
++	 * Hook Switch, 0:On hook , 1:Off hook
++	 */
++	write_data = 0x4F;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data21, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data22, 1);
++
++	return ((rx_data21 & 0x01) && (rx_data22 & 0x01));
++}
++
++static int le88221_init_hw(struct spi_device *spi)
++{
++#if 0
++	int retval;
++	u8 write_data;
++	u8 read_data;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	if (retval < 0) {
++
++	}
++#endif
++
++#if 0
++	u8 tx_buf[] = { 0x00, 0x00, 0x00, 0x00 };
++	u8 rx_buf[] = { 0x00, 0x00, 0x00, 0x00 };
++	struct spi_transfer t[2];
++	struct spi_message m;
++
++	spi_message_init(&m);
++	memset(t, 0, (sizeof t));
++
++	t[0].tx_buf = tx_buf;
++	t[0].len = sizeof(tx_buf);
++	spi_message_add_tail(&t[0], &m);
++
++	t[1].rx_buf = rx_buf;
++	t[1].len = sizeof(rx_buf);
++	spi_message_add_tail(&t[1], &m);
++
++	down(&le88221_lock);
++	spi_sync(flash->spi, &m);
++	up(&le88221_lock);
++
++#endif
++
++	int retval;
++	u8 write_data;
++	u8 read_data;
++
++	// Hardware Reset
++	write_data = 0x04;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// 1ms delay
++	udelay(1000);
++
++	// I/O direction
++	write_data = 0x54;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x02;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0x55;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++
++	// Write Device Register(Define PCLK freq,ie 2.048MHz)
++	write_data = 0x46;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x02;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	write_data = 0x47;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// Read Revision Code Number (RCN)
++	write_data = 0x73;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	printk("Revision:0x%02x\n", read_data);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	printk("Product:0x%02x\n", read_data);
++
++	/* 
++	 * Write SRP register for Flyback power supply(VBL reference) 
++	 * Note there should be voltages on VBH, VBL, VREF after the following codes are invoked.
++	 */
++	write_data = 0xE4;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x05;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x80;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0xE5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++    
++	// Write SRC register
++	write_data = 0xE6;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x07;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0xE7;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);   
++#endif
++    
++    	// wait 100ms delay until switing regulator is stable
++	mdelay(100);
++
++	// System State Register
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#ifdef Print_Reg
++	write_data = 0x57;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif    
++
++	// I/O Data Register
++	write_data = 0x52;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0x53;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif        
++
++	/*
++	 * For channel 1,2 operation
++	 */
++	write_data = 0x4A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x03;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0x4B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++
++	// Operating Functions
++	write_data = 0x60;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x3F;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0x61;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++
++	// Operating Conditions
++	write_data = 0x70;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0x71;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++
++	// Loop Supervision Parameters  19 88 A4 00 */
++	write_data = 0xC2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x19;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x88;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA4;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// DC Feed Parameters  2C 08
++	write_data = 0xC6;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x08;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// Signal Generator A and B Parameters  00 04 25 00 37 3E C3 00 00 00 00
++	write_data = 0xD2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x04;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x25;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x37;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x3E;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xC3;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x44;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x68;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x35;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// Digital Impedance Scaling Network
++	write_data = 0xCA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xEA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0xCB;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++    
++	// Z-Filter (FIR Only) Coefficients BA EB 2A 2C B5 25 AA 24 2C 3D
++	write_data = 0x98;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xBA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xEB;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xB5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x25;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xAA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x24;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x3D;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// Z-Filter (IIR Only) Coefficients  AA BA 27 9F 01
++	write_data = 0x9A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xAA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xBA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x27;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x9F;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x01;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// R-Filter Coefficients  2D 01 2B B0 5A 33 24 5C 35 A4 5A 3D 33 B6
++	write_data = 0x8A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2D;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x01;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xB0;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x5A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x33;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x24;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x5C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x35;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA4;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x5A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x3D;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x33;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xB6;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// X-Filter Coefficients 3A 10 3D 3D B2 A7 6B A5 2A CE 2A 8F
++	write_data = 0x88;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x3A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x10;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x3D;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xB2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA7;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x6B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xCE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x8F;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// GR (Receive Gain A8 71
++	write_data = 0x82;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA8;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x71;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// GX (Transmit Gain) A9 F0
++	write_data = 0x80;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA9;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xF0;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// Voice Path Gains
++	write_data = 0x50;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0x51;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++
++	// B1-Filter (FIR Only) Coefficients  2A 42 22 4B 1C A3 A8 FF 8F AA F5 9F BA F0
++	write_data = 0x86;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x42;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x22;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x4B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x1C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA3;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA8;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x8F;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xAA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xF5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x9F;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xBA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xF0;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// B2-Filter (IIR Only) Coefficients 2E 01
++	write_data = 0x96;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2E;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++ 	write_data = 0x01;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);   
++
++	//le88221_busy_tone(spi);
++	//le88221_dial_tone(spi);
++	//le88221_balanced_ring(spi);
++	le88221_unbalanced_ring(spi);
++
++#if 1
++	while (!le88221_hook_off(spi))
++		; // do nothing
++#endif
++
++#ifdef OPEN_CH1_2
++	SPI_DEBUG("=== Configure channel 1...\n");
++	/*
++	 * For channel 1 operation, Active mode
++	 */
++	//Set Channel Enable and Operating Mode
++	//Channel 1 enabled, Channel 2 disabled
++	write_data = 0x4A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x01;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	//Set Signal generator
++	//0x00: all disabled
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	//Set Operating Conditions
++	//0x00 : all disabled
++	write_data = 0x70;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	//Set System state
++	//Activate codec, Active Low Battery
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x23;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	/*
++	 * If you want loopback test , you can TX_Time_Slot 00, TX_Time_Slot 02
++	 */
++	//Set Transmit time slot
++	write_data = 0x40;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef LEGERITY_LOOPBACK_TEST
++	//Set Receive time slot
++	write_data = 0x42;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x02;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#else
++	//Set Receive time slot
++	write_data = 0x42;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif                                        
++
++	//Read Register Status
++	write_data = 0x4B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	SPI_DEBUG("Read Register Status(0x4B): channel 1 %s, channel 2 %s\n",(rx_data&0x01)?"enabled":"disabled",(rx_data&0x02)?"enabled":"disabled");
++
++	//Read System State Register
++	write_data = 0x57;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	SPI_DEBUG("Read System State Register(0x57): REX=%d, METR=%d, Codec %s, POLNR=%d, SS=0x%x\n",(rx_data&(1<<7)),(rx_data&(1<<6)),(rx_data&(1<<5))?"enabled":"disabled",(rx_data&(1<<4)),(rx_data&0xF));
++    
++	//Read Transmit time slot
++	write_data = 0x41;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	//Read Receive time slot
++	write_data = 0x43;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	SPI_DEBUG("=== Configure channel 2...\n");
++	/* 
++	 * For channel 2 operation, Active mode 
++	 */
++	//Set Channel Enable and Operating Mode
++	//Channel 1 disabled, Channel 2 enabled
++	write_data = 0x4A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x02;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	//Set Signal generator
++	//0x00: all disabled
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	//Set Operating Conditions
++	//0x00 : all disabled
++	write_data = 0x70;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	//Set System state
++	//Activate codec, Active Low Battery
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x23;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	/*
++	 * If you want loopback test , you can TX_Time_Slot 00, TX_Time_Slot 02 
++	 */
++#ifdef LEGERITY_LOOPBACK_TEST
++	// Transmit time slot
++	write_data = 0x40;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x02;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// Receive time slot
++	write_data = 0x42;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#else
++	// Transmit time slot
++	write_data = 0x40;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x01;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// Receive time slot
++	write_data = 0x42;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x01;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++
++	//Read Register Status
++	write_data = 0x4B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	SPI_DEBUG("Read Register Status(0x4B): channel 1 %s, channel 2 %s\n",(rx_data&0x01)?"enabled":"disabled",(rx_data&0x02)?"enabled":"disabled");
++
++	//Read System State Register
++	write_data = 0x57;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	SPI_DEBUG("Read System State Register(0x57): REX=%d, METR=%d, Codec %s, POLNR=%d, SS=0x%x\n",(rx_data&(1<<7)),(rx_data&(1<<6)),(rx_data&(1<<5))?"enabled":"disabled",(rx_data&(1<<4)),(rx_data&0xF));
++
++	//Read Transmit time slot
++	write_data = 0x41;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	SPI_DEBUG("Read Transmit time slot(0x41): Transmit time slot = 0x%02x\n",rx_data&0x7f);
++
++	//Read Receive time slot
++	write_data = 0x43;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	SPI_DEBUG("Read Receive time slot(0x43): Receive time slot = 0x%02x\n",rx_data&0x7f);
++#endif      
++
++	return 0;
++}
++
++void Pcm_Initial_Legerity_Le88221(void)
++{
++	le88221_init_hw(le88221_spidev);
++}
++
++static int __devinit le88221_probe(struct spi_device *spi)
++{
++	le88221_spidev = spi;
++	init_MUTEX(&le88221_lock);
++	return 0;
++}
++
++static int __devexit le88221_remove(struct spi_device *spi)
++{
++	printk("le88221_remove() enter\n");
++	return 0;
++}
++
++static struct spi_driver le88221_driver = {
++	.driver = {
++		.name	= "le88221",
++		.bus	= &spi_bus_type,
++		.owner	= THIS_MODULE,
++	},
++	.probe	= le88221_probe,
++	.remove	= __devexit_p(le88221_remove),
++};
++
++static int le88221_init(void)
++{
++	return spi_register_driver(&le88221_driver);
++}
++
++static void le88221_exit(void)
++{
++	spi_unregister_driver(&le88221_driver);
++}
++
++module_init(le88221_init);
++module_exit(le88221_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Star Semi");
++MODULE_DESCRIPTION("Legerity Le88221 driver");
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/Makefile linux-2.6.35.11-ts7500/arch/arm/mach-str8100/Makefile
+--- linux-2.6.35.11/arch/arm/mach-str8100/Makefile	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,26 @@
++#
++# Makefile for the linux kernel.
++#
++
++# Object file lists.
++
++str8100_demo_pcm_legerity_2phone-objs := str8100_demo_pcm_legerity_config_2phone.o
++str8100_demo_i2s-objs := str8100_demo_i2s_config.o
++str8100_demo_i2s_wm8772-objs := str8100_demo_i2s_wm8772_config.o
++
++obj-y			:= str8100_debug.o str8100_setup.o str8100_timer.o str8100_intc.o str8100_misc.o str8100_counter.o str8100_pm.o str8100_demo_dma.o
++obj-m			:=
++obj-n			:=
++obj-			:=
++
++obj-$(CONFIG_PCI) += str8100_pci.o
++obj-$(CONFIG_STR8100_DMA) += str8100_dma.o
++obj-$(CONFIG_STR8100_HSDMA) += str8100_hsdma.o
++obj-$(CONFIG_STR8100_I2S) += str8100_i2s.o
++obj-$(CONFIG_STR8100_I2S_DEMO) += str8100_demo_i2s.o
++obj-$(CONFIG_STR8100_I2S_WM8772_DEMO) += str8100_demo_i2s_wm8772.o
++obj-$(CONFIG_LE88221_CONTROL) += le88221_control.o
++obj-$(CONFIG_STR8100_PCM_LEGERITY_2PHONE_DEMO) += str8100_demo_pcm_legerity_2phone.o
++obj-$(CONFIG_STR8100_RTC)	+= str8100_rtc.o
++obj-$(CONFIG_STR8100_GPIO)	+= str8100_gpio.o
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/Makefile.boot linux-2.6.35.11-ts7500/arch/arm/mach-str8100/Makefile.boot
+--- linux-2.6.35.11/arch/arm/mach-str8100/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/Makefile.boot	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,11 @@
++# Note: the following conditions must always be true:
++#   ZRELADDR == virt_to_phys(TEXTADDR)
++#   PARAMS_PHYS must be within 4MB of ZRELADDR
++#   INITRD_PHYS must be in RAM
++
++   zreladdr-y	:= 0x00008000
++params_phys-y	:= 0x00000100
++initrd_phys-y	:= 0x00C00000
++# scott.test
++kernel_phys-y	:= 0x00600000
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_counter.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_counter.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_counter.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_counter.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,215 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/time.h>
++#include <linux/init.h>
++#include <linux/timex.h>
++#include <linux/proc_fs.h>
++#include <linux/module.h>
++
++#include <mach/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/time.h>
++
++u64 volatile str8100_counter_tick;
++EXPORT_SYMBOL(str8100_counter_tick);
++
++static struct proc_dir_entry *str8100_counter_proc_entry;
++
++#if 0
++// this is defined in include/asm/arch-str8100/system.h
++u64 str8100_read_counter(void)
++{
++	return (str8100_counter_tick + TIMER2_COUNTER_REG);
++}
++EXPORT_SYMBOL(str8100_read_counter);
++#endif
++
++static int match1=0;
++static int match2=0;
++static void str8100_setup_counter(void)
++{
++	unsigned long control_value;
++	unsigned long mask_value;    
++	unsigned long val;    
++
++	control_value = TIMER1_TIMER2_CONTROL_REG;
++	mask_value = TIMER1_TIMER2_INTERRUPT_MASK_REG;
++
++	TIMER2_COUNTER_REG		= 0;
++	TIMER2_AUTO_RELOAD_VALUE_REG	= 0;
++	TIMER2_MATCH_VALUE1_REG		= match1;
++	TIMER2_MATCH_VALUE2_REG		= match2;
++
++	// Clock Source: PCLK
++	control_value &= ~(1 << TIMER2_CLOCK_SOURCE_BIT_INDEX);
++
++	// UP Count Mode
++	control_value &= ~(1 << TIMER2_UP_DOWN_COUNT_BIT_INDEX);
++
++	// un-mask match1, match2, and overflow interrupt sources
++	mask_value &= ~(0x7 << 3);
++
++	// mask match1, match2 interrupt sources
++	//mask_value |= (0x3 << 3);
++	val=0;
++	if(!match1) val|=0x1;
++	if(!match2) val|=0x2;
++	mask_value |= (val<< 3);
++
++	TIMER1_TIMER2_CONTROL_REG = control_value;
++	TIMER1_TIMER2_INTERRUPT_MASK_REG = mask_value;
++}
++
++static void str8100_counter_enable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER1_TIMER2_CONTROL_REG;
++
++	// enable overflow mode
++	control_value |= (1 << TIMER2_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// enable the timer
++	control_value |= (1 << TIMER2_ENABLE_BIT_INDEX);
++
++	TIMER1_TIMER2_CONTROL_REG = control_value;
++}
++
++static void str8100_counter_disable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER1_TIMER2_CONTROL_REG;
++
++	// enable overflow mode
++	control_value &= ~(1 << TIMER2_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// enable the timer
++	control_value &= ~(1 << TIMER2_ENABLE_BIT_INDEX);
++
++	TIMER1_TIMER2_CONTROL_REG = control_value;
++}
++
++/*
++ * IRQ handler for the timer
++ */
++static irqreturn_t
++str8100_counter_interrupt(int irq, void *dev_id /*, struct pt_regs *regs*/)
++{
++#ifndef CONFIG_VIC_INTERRUPT
++	// clear counter interrrupt status
++	TIMER1_TIMER2_INTERRUPT_STATUS_REG &= ~(1 << TIMER2_OVERFLOW_INTERRUPT_BIT_INDEX);
++#endif
++	str8100_counter_tick += (1ULL << 32);
++	if(match1){
++		TIMER2_MATCH_VALUE1_REG=TIMER2_COUNTER_REG+match1;
++		TIMER1_TIMER2_INTERRUPT_MASK_REG |= (0x1<<3);
++	}
++	if(match2){
++		TIMER2_MATCH_VALUE2_REG=TIMER2_COUNTER_REG+match2;
++		TIMER1_TIMER2_INTERRUPT_MASK_REG |= (0x2<<3);
++	}
++	return IRQ_HANDLED;
++}
++
++static struct irqaction str8100_counter_irq = {
++	.name		= "STR8100 Counter Tick",
++	/* scott.patch */
++	.flags		= IRQF_DISABLED | IRQF_TIMER,
++	.handler	= str8100_counter_interrupt,
++};
++
++static int str8100_counter_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
++{
++	return sprintf(page, "str8100_counter_tick: %llu\n", str8100_counter_tick + TIMER2_COUNTER_REG);
++}
++
++
++static int
++str8100_counter_write_proc(struct file *file, const char __user *buffer,
++	unsigned long count, void *data)
++{
++	char *str;
++	char *cmd;
++
++	if (count > 0) {
++		str = (char *)buffer,
++		cmd = strsep(&str, "\t \n");
++		if (!cmd) goto err_out;
++		if (strcmp(cmd, "match1") == 0) {
++			u32 addr;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 10);
++			match1=addr;
++
++		} else if (strcmp(cmd, "match2") == 0) {
++			u32 addr;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 10);
++			match2=addr;
++
++
++		} else {
++			goto err_out;
++		}
++	}
++	if(match1){
++		TIMER2_MATCH_VALUE1_REG=TIMER2_COUNTER_REG+match1;
++		TIMER1_TIMER2_INTERRUPT_MASK_REG |= (0x1<<3);
++	}
++	if(match2){
++		TIMER2_MATCH_VALUE2_REG=TIMER2_COUNTER_REG+match2;
++		TIMER1_TIMER2_INTERRUPT_MASK_REG |= (0x2<<3);
++	}
++
++	return count;
++
++err_out:
++	return -EFAULT;
++}
++/*
++ * Set up timer interrupt, and return the current time in seconds.
++ */
++int __init str8100_counter_setup(void)
++{
++     
++	str8100_setup_counter();
++	setup_irq(INTC_TIMER2_BIT_INDEX, &str8100_counter_irq);
++	str8100_counter_enable();
++	str8100_counter_proc_entry = create_proc_entry("str8100/counter", S_IFREG | S_IRUGO, NULL);
++	if (str8100_counter_proc_entry) {
++		str8100_counter_proc_entry->read_proc = str8100_counter_read_proc;
++		str8100_counter_proc_entry->write_proc = str8100_counter_write_proc;
++	}
++
++	return 0;
++}
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_debug.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_debug.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_debug.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_debug.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,47 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/types.h>
++#include <mach/hardware.h>
++
++void debug_puts(const char *s)
++{
++	while (*s) {
++		volatile unsigned int status = 0;
++		do {
++			status = _UART_LSR(0);
++		} while (!((status & THR_EMPTY) == THR_EMPTY));
++
++		_UART_THR(0) = *s;
++
++		if (*s == '\n') {
++			do {
++				status = _UART_LSR(0);
++			} while (!((status & THR_EMPTY) == THR_EMPTY));
++
++			_UART_THR(0) = '\r';
++		}
++		s++;
++	}
++}
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_dma.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_dma.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_dma.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_dma.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,576 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++//Options 
++//#define DEBUG_PRINT	
++//=================================================================================
++
++#include <linux/kernel.h>	/* printk() */
++#include <linux/delay.h>
++#include <mach/star_demo_dma.h>
++#include <mach/star_i2s.h>
++#include <mach/star_powermgt.h>
++#include <mach/star_misc.h>
++#include <mach/star_gpio.h>
++
++#ifdef DEBUG_PRINT
++#undef DEBUG_PRINT
++//#define DEBUG_PRINT(arg...) if(debug) printk(arg);
++#define DEBUG_PRINT printk
++#else
++#define DEBUG_PRINT(arg...) 
++#endif
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  Hal_Dmac_Get_Channel_Transfer_Unit_Number
++ * PURPOSE:   
++ *
++ ******************************************************************************/
++u32 Hal_Dmac_Get_Channel_Transfer_Unit_Number(u32 byte_size, u32 src_width)
++{
++    u32    transfer_unit_num;
++    
++    
++    if (src_width == DMAC_CH_SRC_WIDTH_8_BITS)  // 8-bit
++    {
++        transfer_unit_num = byte_size;
++    }
++    else if (src_width == DMAC_CH_SRC_WIDTH_16_BITS)  // 16-bit
++    {
++        if (byte_size % 2)
++        {
++            transfer_unit_num = (byte_size >> 1) + 1;
++        }
++        else
++        {
++            transfer_unit_num = (byte_size >> 1);
++        }
++    }
++    else if (src_width == DMAC_CH_SRC_WIDTH_32_BITS)  // 32-bit
++    {
++        if (byte_size % 4)
++        {
++            transfer_unit_num = (byte_size >> 2) + 1;
++        }
++        else
++        {
++            transfer_unit_num = (byte_size >> 2);
++        }
++    }
++    else
++    {
++        transfer_unit_num = 0;
++    }
++    
++    return transfer_unit_num;
++}
++EXPORT_SYMBOL(Hal_Dmac_Get_Channel_Transfer_Unit_Number);
++
++
++void Hal_Dmac_Configure_DMA_Handshake(DMAC_HARDWARE_HANDSHAKE_OBJ_T *dmac_obj)
++{
++    u32    channel_control, ch;
++
++    /*
++     * Configure DMA controller for UART's hardware DMA handshake mode
++     */    
++
++	/*
++	 * Stop mplayer will also stop PCM if disable GDMA Controller.
++	 * Changed to disable corresponding channels only.
++	 */
++	//HAL_DMAC_DISABLE();
++	for (ch = 0; ch < DMAC_MAX_CHANNEL_NUM; ch++)
++	{
++		if (dmac_obj->channel_id & DMAC_CH_ID(ch))
++			HAL_DMAC_DISABLE_CHANNEL(ch);
++	}
++	
++//#if (ENDIAN_MODE == BIG_ENDIAN)
++#if 0
++    /*Set Master0 and Master 1 endianness as Big Endian*/
++    HAL_DMAC_SET_MASTER0_BIG_ENDIAN();
++    HAL_DMAC_SET_MASTER1_BIG_ENDIAN();
++#else
++    /*Set Master0 and Master 1 endianness as Little Endian*/
++    HAL_DMAC_SET_MASTER0_LITTLE_ENDIAN();
++    HAL_DMAC_SET_MASTER1_LITTLE_ENDIAN();
++#endif
++
++    //Clear TC interrupt status    
++    HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(0xFF);        // 8 channels
++
++    //Clear Errot/Abort interrupt status    
++    HAL_DMAC_CLEAR_ERROR_ABORT_INTERRUPT_STATUS(0x00FF00FF);    // 8 channels
++
++    /*
++     * Configure DMA's channel control
++     */   
++    channel_control = ((DMAC_CH_TC_MASK_DISABLE << 31) | \
++                       ((dmac_obj->target_select&0xf) << 25) | \
++                       (DMAC_CH_PRI_LEVEL_3 << 22) | \
++                       (DMAC_CH_PROT3_NON_CACHEABLE << 21) | \
++                       (DMAC_CH_PROT2_NON_BUFFERABLE << 20) | \
++                       (DMAC_CH_PROT1_PRIVILEGED_MODE << 19) | \
++                       ((dmac_obj->src_burst_size&0x7) << 16) | \
++                       ((dmac_obj->src_width&0x7) << 11) | \
++                       ((dmac_obj->dst_width&0x7) << 8) | \
++                       (DMAC_CH_MODE_HW_HANDSHAKE << 7) | \
++                       ((dmac_obj->srcad_ctl&0x3) << 5) | \
++                       ((dmac_obj->dstad_ctl&0x3) << 3) | \
++                       (dmac_obj->src_master << 2) | \
++                       (dmac_obj->dst_master << 1) | \
++                       (DMAC_CH_DISABLE));
++
++#if 0
++    // for testing only
++    if (dmac_obj->llp_addr != 0)
++    {
++        /*
++         * For LLP hardware handshaking with at least one descriptors, disable TC interrupt 
++         * of the first descriptor.
++         */
++        channel_control |= (DMAC_CH_TC_MASK_ENABLE << 31);
++    }
++#endif
++    for (ch = 0; ch < DMAC_MAX_CHANNEL_NUM; ch++)
++    {
++        if (dmac_obj->channel_id & DMAC_CH_ID(ch))
++        {  
++            /*
++             * Configure channel's CSR register
++             */
++            DMAC_CH_CSR_REG(ch) = channel_control & 0xFFFFFFFE; //Disable CH(n) DMA
++                
++            /*
++             * Configure channel's CFG register: disable channel abort interrupt,
++             * enable channel error and terminal count interrupts.
++             */
++            DMAC_CH_CFG_REG(ch) |= (0x07);
++            DMAC_CH_CFG_REG(ch) &= ~((0x3));
++        }                               	
++    }
++
++    for (ch = 0; ch < DMAC_MAX_CHANNEL_NUM; ch++)
++    {
++        if (dmac_obj->channel_id & DMAC_CH_ID(ch))
++        {  
++            //Set Src address register
++            DMAC_CH_SRC_ADDR_REG(ch)= dmac_obj->src_addr;
++
++            //Set Dst address register
++            DMAC_CH_DST_ADDR_REG(ch)= dmac_obj->dst_addr;    
++
++            //Set Transfer Number
++            if (dmac_obj->src_width == DMAC_CH_SRC_WIDTH_8_BITS)
++            {
++                DMAC_CH_SIZE_REG(ch) = (dmac_obj->transfer_bytes & 0x0FFF);
++                DEBUG_PRINT("%s: 8-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,dmac_obj->transfer_bytes,ch,DMAC_CH_SIZE_REG(ch));
++            }
++            else if (dmac_obj->src_width == DMAC_CH_SRC_WIDTH_16_BITS)
++            {                                  
++                DMAC_CH_SIZE_REG(ch) = ((dmac_obj->transfer_bytes >> 1) + (dmac_obj->transfer_bytes % 2)) & 0x0FFF;
++                DEBUG_PRINT("%s: 16-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,dmac_obj->transfer_bytes,ch,DMAC_CH_SIZE_REG(ch));
++            }
++            else if (dmac_obj->src_width == DMAC_CH_SRC_WIDTH_32_BITS)
++            {
++                DMAC_CH_SIZE_REG(ch) = ((dmac_obj->transfer_bytes >> 2) + ((dmac_obj->transfer_bytes % 4) ? 1 : 0)) & 0x0FFF;
++                DEBUG_PRINT("%s: 32-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,dmac_obj->transfer_bytes,ch,DMAC_CH_SIZE_REG(ch));
++            }
++            else
++            {
++            	DEBUG_PRINT("%s: dead\n",__FUNCTION__);
++                while (1);
++            }
++
++            //Enable Channel DMA transfer 
++            HAL_DMAC_ENABLE_CHANNEL(ch);
++             
++            //Set Channel's Sync logic
++            DMAC_SYNC_REG |= (1 << ch);
++
++            /*
++             * Configure channel LLP if LLP is enabled
++             */
++            DMAC_CH_LLP_REG(ch) = (dmac_obj->llp_addr == 0) ? 0 : (dmac_obj->llp_addr & 0xFFFFFFFC);
++        }
++    }
++}
++EXPORT_SYMBOL(Hal_Dmac_Configure_DMA_Handshake);
++
++irqreturn_t str8100_dma_err_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 dma_error_status,dma_ch;
++printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++
++	HAL_DMAC_READ_ERROR_ABORT_INTERRUPT_STATUS(dma_error_status);
++	for (dma_ch = 0; dma_ch < DMAC_MAX_CHANNEL_NUM; dma_ch++)
++	{
++		if (dma_error_status & DMAC_CH_ID(dma_ch))
++		{
++			printk("%s: this_irq=%d, DMA channel error on ch %d\n",__FUNCTION__,this_irq,dma_ch);
++			HAL_DMAC_DISABLE_CHANNEL(dma_ch);
++			HAL_DMAC_CLEAR_ERROR_ABORT_INTERRUPT_STATUS(DMAC_CH_ID(dma_ch));
++		}
++	}	
++	
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++	return IRQ_HANDLED;
++}
++EXPORT_SYMBOL(str8100_dma_err_irq_handler);
++
++static const u32 rate_map[3][4]={	{48000,    0,    0,    0},
++					{44100,22050,11025, 5512},
++					{32000,16000, 8000,    0}};
++    /*
++     * Configure I2S related parameters
++     */
++/*//#define i2s_sdata_width	I2S_DATA_16_BIT
++#define i2s_sdata_width		I2S_DATA_32_BIT
++#define i2s_mode	 	I2S_SLAVE_MODE
++//#define i2s_mode		I2S_MASTER_MODE
++#define i2s_tranfer_timing_ctrl	I2S_I2S_MODE
++//#define i2s_tranfer_timing_ctrl	I2S_RJF_MODE
++//#define i2s_tranfer_timing_ctrl	I2S_LJF_MODE
++#define i2s_sclk_mode		I2S_CLOCK_CONTINUOUS_MODE
++//#define i2s_sclk_mode		I2S_CLOCK_256S_MODE
++*/
++
++//int str8100_i2s_init(sampling_rate,I2S_DATA_32_BIT, I2S_MASTER_MODE, I2S_I2S_MODE, I2S_CLOCK_256S_MODE);
++//int str8100_i2s_init(sampling_rate,I2S_DATA_32_BIT, I2S_SLAVE_MODE, I2S_I2S_MODE, I2S_CLOCK_CONTINUOUS_MODE);
++
++int str8100_i2s_init(int sampling_rate,u32 i2s_sdata_width, u32 i2s_mode,
++			u32 i2s_tranfer_timing_ctrl, u32 i2s_sclk_mode){
++	u32 tmp;
++	u32 i/*clock*/ ,j,i2s_src_clk_div;
++	DEBUG_PRINT("%s: sampling_rate=%d\n",__FUNCTION__,sampling_rate);
++	
++	for(i=0;i<3;i++)
++		for(j=0;j<4;j++)
++			if(rate_map[i][j]==sampling_rate) goto rate_match;
++
++rate_match:
++	if(i==3&&j==4) {
++		printk("%s: unsupported sampling rate (%d)\n",__FUNCTION__,sampling_rate);
++		return -1;
++	}else{
++		DEBUG_PRINT("%s: clock=%d,src_clk_div=%d\n",__FUNCTION__,i,j);
++	}
++	
++	i2s_src_clk_div=j;
++
++	/*
++	 * Select I2S clock source; here we use 48K sampling rate for the target file.
++	 */
++	 
++//	switch(sampling_rate){
++	switch(i/*clock*/){
++	case 0/*48000*/: 
++		HAL_PWRMGT_I2S_CLOCK_SOURCE_12288000HZ(); 
++		break; 
++	case 1/*44100*/:
++		HAL_PWRMGT_I2S_CLOCK_SOURCE_11289600HZ(); 
++		break;
++	case 2/*32000*/: 
++		HAL_PWRMGT_I2S_CLOCK_SOURCE_8192000HZ(); 
++		break; 
++	}
++
++	HAL_PWRMGT_CONFIGURE_CLOCK_OUT_PIN(11,0);
++	
++	// Enable I2S pins
++	HAL_MISC_ENABLE_I2S_PINS();
++	
++	// Enable I2S clock
++	HAL_PWRMGT_ENABLE_I2S_CLOCK(); 
++
++	//Hal_Pwrmgt_Software_Reset(PWRMGT_P2S_SOFTWARE_RESET_BIT_INDEX);
++
++
++    /*
++     * Configure I2S to be Master & Transmitter
++     * Note the I2S's WS Clock is derived from Clock & Power Management Functional
++     * Block!!
++     */
++	I2S_CONFIGURATION_REG = 
++                        (i2s_sdata_width << 0) |
++                        (i2s_src_clk_div << 4) |
++                        (0x1 << 12) |   /* Use I2SSD as data output pin and GPIOA[3] as data input pin for full-duplex mode */
++                        (0x0 << 15) |   /* Disable clock phase invert */
++                        (0x0 << 24) |   /* Disable I2S data swap */
++                        ((i2s_sclk_mode & 0x1) << 25) |
++                        ((i2s_tranfer_timing_ctrl & 0x3) << 26) |
++                        (0x0 << 29) |   /* Enable I2S Transmitter */
++			(i2s_mode << 30) |
++			(0x0 << 31);	/* Disable I2S */
++
++	//Enable none while initializing
++	I2S_INTERRUPT_ENABLE_REG = 0x0;
++//	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG | I2S_TXBF_R_EMPTY_FLAG | I2S_TXBF_L_EMPTY_FLAG);
++
++    // Clear spurious interrupt sources
++    I2S_INTERRUPT_STATUS_REG = 0xF0;
++
++    tmp = I2S_LEFT_RECEIVE_DATA_REG;
++    tmp = I2S_RIGHT_RECEIVE_DATA_REG;
++
++    // Disable I2S
++    HAL_I2S_DISABLE_I2S();
++
++	return 0;
++}
++EXPORT_SYMBOL(str8100_i2s_init);
++
++
++
++/*
++ * Define which GPIO Pins will serve as Winbond's W571C161's SSP (Serial Setup
++ * Potr) Pins which consist of SSPEN, SSPCLK, and SSPTR.
++ * Note these three pins are uni-directional output pins:
++ * SSPEN  : mapping to COM1 pin
++ * SSPCLK : mapping to COM2 pin
++ * SSPTR  : mapping to COM3 pin
++ */
++//#define SSPEN_GPIO_INDEX        (3)   /* use GPIOA #3 as WM8772's COM1 */
++#define SSPEN_GPIO_INDEX        (0)   /* use GPIOA #3 as WM8772's COM1 */
++
++#define SSPCLK_GPIO_INDEX       (1)   /* use GPIOA #4 as WM8772's COM2 */
++
++#define SSPTR_GPIO_INDEX        (2)   /* use GPIOA #5 as WM8772's COM3 */
++
++#define SWITCH_GPIO_INDEX       (7)   /* use GPIOA #6 as WM8772's Transfer or Receiver */
++
++/*
++ * Macro-defines to "output" SSPEN, SSPCLK and SSPTR
++ */
++#define SSPEN_HIGH()            HAL_GPIOA_SET_DATA_OUT_HIGH(0x1 << SSPEN_GPIO_INDEX)
++
++#define SSPEN_LOW()             HAL_GPIOA_SET_DATA_OUT_LOW(0x1 << SSPEN_GPIO_INDEX)
++
++
++#define SSPCLK_HIGH()           HAL_GPIOA_SET_DATA_OUT_HIGH(0x1 << SSPCLK_GPIO_INDEX)
++
++#define SSPCLK_LOW()            HAL_GPIOA_SET_DATA_OUT_LOW(0x1 << SSPCLK_GPIO_INDEX)
++
++
++#define SSPTR_HIGH()            HAL_GPIOA_SET_DATA_OUT_HIGH(0x1 << SSPTR_GPIO_INDEX)
++
++#define SSPTR_LOW()             HAL_GPIOA_SET_DATA_OUT_LOW(0x1 << SSPTR_GPIO_INDEX)
++
++
++/*
++ * SWITCH TX/RX For ASIC VER.
++ */
++#define SSPSW_HIGH()            HAL_GPIOA_SET_DATA_OUT_HIGH(0x1 << SWITCH_GPIO_INDEX)
++
++#define SSPSW_LOW()             HAL_GPIOA_SET_DATA_OUT_LOW(0x1 << SWITCH_GPIO_INDEX)
++
++/*
++ * Macro-defines to configure the "directions" of SSPEN, SSPCLK and SSPTR
++ */
++#define SSPEN_DIR_OUT()         HAL_GPIOA_SET_DIRECTION_OUTPUT(0x1 << SSPEN_GPIO_INDEX)
++
++#define SSPCLK_DIR_OUT()        HAL_GPIOA_SET_DIRECTION_OUTPUT(0x1 << SSPCLK_GPIO_INDEX)
++
++#define SSPTR_DIR_OUT()         HAL_GPIOA_SET_DIRECTION_OUTPUT(0x1 << SSPTR_GPIO_INDEX)
++
++//For ASIC
++#define SSPSW_DIR_OUT()         HAL_GPIOA_SET_DIRECTION_OUTPUT(0x1 << SWITCH_GPIO_INDEX)
++
++
++#define TIME_FACTOR               (20)
++
++/*
++ * Function prototype declaration
++ */
++u32            I2s_Gpio_SSP_Initialise(void);
++
++void           I2s_Gpio_SSP_Write(u16);
++
++void           I2s_Gpio_SSP_Switch_To_Record_Data(void);
++
++void           I2s_Gpio_SSP_Switcg_To_Playback_Data(void);
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  I2s_Gpio_SSP_Initialise
++ * PURPOSE:   
++ *
++ ******************************************************************************/
++u32 I2s_Gpio_SSP_Initialise(void)
++{
++ 
++    // Enable GPIO clock
++    HAL_PWRMGT_ENABLE_GPIO_CLOCK();
++
++    // Perform GPIO software reset
++//    Hal_Pwrmgt_Software_Reset(PWRMGT_GPIO_SOFTWARE_RESET_BIT_INDEX);
++
++
++    /*
++     * 1. Determine/Check which three GPIO pins will serve as SSPEN, SSPCLK and 
++     *    SSPTR pins
++     * 2. At initialization :
++     *    SSPEN  : Output Direction, High state
++     *    SSPCLK : Output Direction, Low state
++     *    SSPTR  : Output Direction, Low state
++     */
++    SSPEN_DIR_OUT();
++    
++    SSPCLK_DIR_OUT();
++    
++    SSPTR_DIR_OUT();
++
++
++    /*
++     * Set SSPEN to be HIGH and SSPCLK/SSPTR be be LOW to "Free" SSP Bus
++     */
++     
++    SSPEN_HIGH();
++
++#if 1
++    SSPCLK_LOW();
++
++    SSPTR_LOW();
++#else
++    SSPCLK_HIGH();
++
++    SSPTR_HIGH();
++#endif
++
++    return 0;  // for success indication
++}
++EXPORT_SYMBOL(I2s_Gpio_SSP_Initialise);
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  I2s_Gpio_SSP_Write
++ * PURPOSE:   
++ *
++ ******************************************************************************/
++void I2s_Gpio_SSP_Write(u16 reg_data)
++{
++    unsigned long   cpsr_flags;
++    u32 volatile    ii;
++
++
++	local_irq_save(cpsr_flags);
++    
++    SSPEN_HIGH();
++
++    SSPCLK_LOW();
++
++    SSPTR_LOW();
++
++    ndelay(2 * TIME_FACTOR);
++
++    SSPEN_LOW();
++
++    // Output D15 ~ D0 of reg_data
++    for (ii = 0; ii < 16; ii++)
++    {
++        SSPCLK_LOW();
++    
++        ndelay(3 * TIME_FACTOR);//setup time
++        
++        if (reg_data & 0x8000)
++        {
++            SSPTR_HIGH();
++        }
++        else
++        {
++            SSPTR_LOW();
++        }
++        
++        ndelay(5 * TIME_FACTOR);
++        
++        SSPCLK_HIGH();
++        
++        ndelay(5 * TIME_FACTOR);//hold time
++
++        SSPCLK_LOW();
++        
++        ndelay(3 * TIME_FACTOR);
++
++        // Shift left by one bit to get the next data bit
++        reg_data <<= 1;
++    }
++    
++    SSPEN_HIGH();
++
++    SSPCLK_LOW();
++
++    ndelay(1 * TIME_FACTOR);
++
++    // for testing only
++#if 0
++    SSPCLK_HIGH();
++
++//    SSPTR_HIGH();
++#endif
++
++
++    // Delay some time
++//    for (ii = 0; ii < 0x100000; ii++);    
++
++	local_irq_restore(cpsr_flags);
++}
++EXPORT_SYMBOL(I2s_Gpio_SSP_Write);
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  I2s_Gpio_SSP_Switch_To_Record_Data
++ * PURPOSE:   
++ *
++ ******************************************************************************/
++void I2s_Gpio_SSP_Switch_To_Record_Data(void)
++{
++    SSPSW_DIR_OUT();
++    
++    SSPSW_HIGH();
++}
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  I2s_Gpio_SSP_Switcg_To_Playback_Data
++ * PURPOSE:   
++ *
++ ******************************************************************************/
++void I2s_Gpio_SSP_Switcg_To_Playback_Data(void)
++{
++    SSPSW_DIR_OUT();
++    
++    SSPSW_LOW();
++}
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_i2s_config.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_i2s_config.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_i2s_config.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_i2s_config.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,471 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++
++#include <linux/kernel.h>	/* printk() */
++#include <linux/errno.h>	/* error codes */
++#include <linux/types.h>	/* size_t */
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++#include <linux/pci.h>
++
++#include <asm/system.h>		/* cli(), *_flags */
++#include <asm/uaccess.h>	/* copy_*_user */
++
++#include <mach/star_powermgt.h>
++#include <mach/star_misc.h>
++#include <mach/star_i2s.h>
++#include <mach/star_demo_dma.h>
++
++MODULE_AUTHOR("Mac Lin");
++MODULE_LICENSE("Dual BSD/GPL");
++
++
++#define CONFIG_I2S_USE_DMA
++//Debug = left only
++#define DEBUG	
++
++static struct proc_dir_entry *star_i2s_proc_entry=NULL;
++static u32 sampling_rate=44100;
++static u32 sample_size=16;
++
++module_param(sampling_rate, int, 0);
++MODULE_PARM_DESC(gpio, "sampling_rate");
++
++module_param(sample_size, int, 0);
++MODULE_PARM_DESC(gpio, "sample_size");
++
++#define DMA_TRANSFER_MAX_BYTE    (0xfff<<(sample_size>>4)) 
++#define BUFSIZE (0xfff<<4) //twice the 32-bit DMA transfer byte size
++
++static u8* lbuffer;
++static u8* lbuffer_p;
++static u32 llen=0;
++static u32 lpos=0;
++static u32 i2s_err_lur=0;
++
++static u32 debug=0;
++#define DEBUG_PRINT(arg...) if(debug) printk(arg);
++
++//=================================================================================
++//
++#ifdef CONFIG_I2S_USE_DMA
++
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8759_dma_handshake_left_tx;
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8759_dma_handshake_right_tx;
++
++static u32                          i2s_wm8759_dma_right_tx_channel = 1;
++
++
++
++
++
++void I2s_WM8759_Configure_DMA_Hardware_Handshake(void)
++{
++    /*
++     * Configure DMA's channel setting for I2S's Left Channel Tx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    i2s_wm8759_dma_handshake_left_tx.channel_num = 0;
++    i2s_wm8759_dma_handshake_left_tx.channel_id = DMAC_CH_ID(i2s_wm8759_dma_handshake_left_tx.channel_num);
++    i2s_wm8759_dma_handshake_left_tx.target_select = DMAC_HW_HAND_SHAKE_I2S_TX_LEFT_ID;
++    i2s_wm8759_dma_handshake_left_tx.src_addr = (u32)lbuffer_p;
++    i2s_wm8759_dma_handshake_left_tx.src_master = DMAC_CH_SRC_SEL_M1;
++    i2s_wm8759_dma_handshake_left_tx.dst_master = DMAC_CH_DST_SEL_M0;
++    i2s_wm8759_dma_handshake_left_tx.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;
++    i2s_wm8759_dma_handshake_left_tx.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;
++    
++	switch(sample_size){
++	case 16:
++		i2s_wm8759_dma_handshake_left_tx.dst_addr = (SYSPA_I2S_BASE_ADDR + 0xCA);
++		i2s_wm8759_dma_handshake_left_tx.src_width = DMAC_CH_SRC_WIDTH_16_BITS;
++		i2s_wm8759_dma_handshake_left_tx.dst_width = DMAC_CH_DST_WIDTH_16_BITS;
++		break;
++	case 32:
++		i2s_wm8759_dma_handshake_left_tx.dst_addr = (SYSPA_I2S_BASE_ADDR + 0xC8);
++		i2s_wm8759_dma_handshake_left_tx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++		i2s_wm8759_dma_handshake_left_tx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++		break;
++	}
++
++//    i2s_wm8759_dma_handshake_left_tx.dst_width = DMAC_CH_DST_WIDTH_16_BITS;
++
++    /*
++     * Note here the total number of bytes for each DMA transfer is specified!!
++     */
++//    i2s_wm8759_dma_handshake_left_tx.transfer_bytes = DMA_TRANSFER_MAX_BYTE;
++    i2s_wm8759_dma_handshake_left_tx.transfer_bytes = (llen<DMA_TRANSFER_MAX_BYTE)?llen:DMA_TRANSFER_MAX_BYTE;
++
++    i2s_wm8759_dma_handshake_left_tx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;   
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8759_dma_handshake_left_tx);
++
++#ifndef DEBUG 
++    /*
++     * Configure DMA's channel setting for I2S's Right Channel Tx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    i2s_wm8759_dma_handshake_right_tx.channel_id = DMAC_CH_ID(i2s_wm8759_dma_right_tx_channel);
++    
++    i2s_wm8759_dma_handshake_right_tx.target_select = DMAC_HW_HAND_SHAKE_I2S_TX_RIGHT_ID;
++
++    i2s_wm8759_dma_handshake_right_tx.src_addr = (u32)rbuffer_p;
++
++    i2s_wm8759_dma_handshake_right_tx.dst_addr = (SYSPA_I2S_BASE_ADDR + 0xC4);
++
++    i2s_wm8759_dma_handshake_right_tx.src_master = DMAC_CH_SRC_SEL_M1;
++    
++    i2s_wm8759_dma_handshake_right_tx.dst_master = DMAC_CH_DST_SEL_M0;
++
++    i2s_wm8759_dma_handshake_right_tx.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;
++    
++    i2s_wm8759_dma_handshake_right_tx.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;
++
++    i2s_wm8759_dma_handshake_right_tx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    
++    i2s_wm8759_dma_handshake_right_tx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    /*
++     * Note here the total number of bytes for each DMA transfer is specified!!
++     */
++    i2s_wm8759_dma_handshake_right_tx.transfer_bytes = DMA_TRANSFER_MAX_BYTE;
++
++    i2s_wm8759_dma_handshake_right_tx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;   
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8759_dma_handshake_right_tx);
++#endif
++    return;
++}
++#endif //CONFIG_I2S_USE_DMA
++
++
++//=================================================================================
++//
++
++extern void str8100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++
++#ifdef CONFIG_I2S_USE_DMA
++static irqreturn_t str8100_dma_tc_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 dma_tc_status,tot_size;
++	u32 len;
++//printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++
++    HAL_DMAC_READ_TERMINAL_COUNT_INTERRUPT_STATUS(dma_tc_status);
++
++    /*
++     * For DMA's Tx for I2S Left Channel
++     */
++	if (dma_tc_status & DMAC_CH_ID(i2s_wm8759_dma_handshake_left_tx.channel_num))
++	{                      
++		HAL_DMAC_DISABLE_CHANNEL(i2s_wm8759_dma_handshake_left_tx.channel_num);
++		HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8759_dma_handshake_left_tx.channel_num));
++		lpos+=i2s_wm8759_dma_handshake_left_tx.transfer_bytes;
++		if(lpos<llen){
++			/*
++			 * Re-initialize DMA's channel for Left_Tx
++			 */
++			DMAC_CH_SRC_ADDR_REG(i2s_wm8759_dma_handshake_left_tx.channel_num) = (u32)lbuffer_p+lpos;
++			DMAC_CH_DST_ADDR_REG(i2s_wm8759_dma_handshake_left_tx.channel_num) = (SYSPA_I2S_BASE_ADDR + 0xC8);        
++			
++			/*
++			 * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
++			 * number of source transfer width!
++			 */        
++			len=(llen - lpos);
++			i2s_wm8759_dma_handshake_left_tx.transfer_bytes= (len<DMA_TRANSFER_MAX_BYTE)?len:DMA_TRANSFER_MAX_BYTE;
++
++			if (i2s_wm8759_dma_handshake_left_tx.src_width == DMAC_CH_SRC_WIDTH_16_BITS)
++			{
++			    tot_size = (i2s_wm8759_dma_handshake_left_tx.transfer_bytes >> 1) + ((i2s_wm8759_dma_handshake_left_tx.transfer_bytes % 2) ? 1 : 0);
++			}
++			else if (i2s_wm8759_dma_handshake_left_tx.src_width == DMAC_CH_SRC_WIDTH_32_BITS)
++			{
++			    tot_size = (i2s_wm8759_dma_handshake_left_tx.transfer_bytes >> 2) + ((i2s_wm8759_dma_handshake_left_tx.transfer_bytes % 4) ? 1 : 0);
++			}
++			else
++			{
++			    tot_size = i2s_wm8759_dma_handshake_left_tx.transfer_bytes;
++			}
++			
++			DMAC_CH_SIZE_REG(i2s_wm8759_dma_handshake_left_tx.channel_num) = tot_size & 0x0FFF;
++			HAL_DMAC_ENABLE_CHANNEL(i2s_wm8759_dma_handshake_left_tx.channel_num);
++//printk("%s: 32-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,i2s_wm8759_dma_handshake_left_tx.transfer_bytes,i2s_wm8759_dma_handshake_left_tx.channel_num,DMAC_CH_SIZE_REG(i2s_wm8759_dma_handshake_left_tx.channel_num));
++
++	}else{
++		llen=lpos=0;
++	}
++	}
++
++
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++#endif //CONFIG_I2S_USE_DMA
++
++static irqreturn_t str8100_i2s_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 interrupt_status;
++	DEBUG_PRINT("%s: this_irq=%d, I2S_INTERRUPT_STATUS_REG=0x%.8x,llen=%d,lpos=%d\n",__FUNCTION__,this_irq,I2S_INTERRUPT_STATUS_REG,llen,lpos);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++	interrupt_status = I2S_INTERRUPT_STATUS_REG;   
++if((llen<lpos)||llen==0)     HAL_I2S_DISABLE_I2S();
++
++#ifndef CONFIG_I2S_USE_DMA
++		I2S_RIGHT_TRANSMIT_DATA_REG=0;
++
++	if ((lpos<=llen) && (interrupt_status & I2S_TXBF_L_EMPTY_FLAG)){
++		switch(sample_size){
++			case 16:
++				I2S_LEFT_TRANSMIT_DATA_REG=(*((u16*)(&lbuffer[lpos])))<<16;lpos+=2;
++				break;
++			case 32:
++				I2S_LEFT_TRANSMIT_DATA_REG=*((u32*)(&lbuffer[lpos]));lpos+=4;
++				break;
++		}
++		
++		if(lpos>llen){
++			// Disable Left Channel's Transmit Buffer Interrupt Sources
++			I2S_INTERRUPT_ENABLE_REG &= ~(I2S_TXBF_L_EMPTY_FLAG | I2S_TXBF_L_UR_FLAG);
++			lpos=llen=0;
++		}
++	}
++#endif //!CONFIG_I2S_USE_DMA
++
++
++	if (llen>=lpos && (interrupt_status & I2S_TXBF_L_UR_FLAG)){
++		// Clear I2S interrupt status
++		i2s_err_lur++;
++		if(i2s_err_lur>10)
++			I2S_INTERRUPT_ENABLE_REG &= ~(I2S_TXBF_L_UR_FLAG);
++//			HAL_I2S_DISABLE_I2S();
++		
++		printk("%s: Left Channel Tx Underrun!,llen=%d, lpos=%d, interrupt_status=%.8x,i2s_err_lur=%d\n",__FUNCTION__,llen,lpos,interrupt_status,i2s_err_lur);
++	}
++	I2S_INTERRUPT_STATUS_REG &= 0xf0;
++
++	
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++
++
++//=================================================================================
++static int proc_read_i2s(char *buf, char **start, off_t offset,
++                   int count, int *eof, void *data)
++{
++	int len=0;
++	DEBUG_PRINT("%s:\n",__FUNCTION__);
++	len += sprintf(buf,	"sampling_rate=%d\n"
++				"sample_size=%d\n"
++			,sampling_rate,sample_size); 
++	*eof = 1;
++	return len;
++}
++
++static proc_write_i2s(struct file *file, const char *buffer, unsigned long count, void *data){
++	int len=0;
++	DEBUG_PRINT("%s: sample size %d, sampling rate %d, count=%d\n",__FUNCTION__,sample_size,sampling_rate,count);
++	
++	//is buffer free?
++	if(lpos!=llen){
++		printk("%s: buffer not free\n");
++		return -EBUSY;
++	}
++	if(sampling_rate!=32000&&sampling_rate!=44100&&sampling_rate!=48000){
++		printk("%s: invalid sampling rate(%d)\n",sampling_rate);
++		return -EFAULT;
++	}
++	if(sample_size!=16&&sample_size!=32){
++		printk("%s: invalid sample size(%d)\n",sample_size);
++		return -EFAULT;
++	}
++
++	//copy the raw data to local buffer	
++	if(count>BUFSIZE) len=BUFSIZE;
++	else len=count;
++	
++	if(copy_from_user(lbuffer,buffer,len)){
++		return -EFAULT;	
++	}
++	llen=len;
++	lpos=0;
++	i2s_err_lur=0;
++	
++	str8100_i2s_init(sampling_rate,I2S_DATA_32_BIT, I2S_MASTER_MODE, I2S_I2S_MODE, I2S_CLOCK_256S_MODE);
++
++#ifdef CONFIG_I2S_USE_DMA
++    /*
++     * Configure DMA for hardware handshake for I2S
++     * Note the DMA is NOT enabled after invoking the following function, but the specified
++     * DMA channels are enabled!!
++     */
++    i2s_wm8759_dma_right_tx_channel = 1;   
++
++    I2s_WM8759_Configure_DMA_Hardware_Handshake();  
++
++#endif //CONFIG_I2S_USE_DMA
++	//fill the tx left/right registers
++
++		switch(sample_size){
++			case 16:
++				I2S_LEFT_TRANSMIT_DATA_REG=(*((u16*)(&lbuffer[lpos])))<<16;lpos+=2;
++				break;
++			case 32:
++				I2S_LEFT_TRANSMIT_DATA_REG=*((u32*)(&lbuffer[lpos]));lpos+=4;
++				break;
++		}
++
++	I2S_RIGHT_TRANSMIT_DATA_REG=0;
++
++#ifdef CONFIG_I2S_USE_DMA
++	/*
++	 * Enable I2S's interrupt sources
++	 * Note for DMA hardware handshake, we only need to enable Left/Right Channel's 
++	 * Transmit Buffer Underrun.
++	 */
++#ifdef DEBUG	
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_L_UR_FLAG);
++#else
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG);
++#endif
++#else //CONFIG_I2S_USE_DMA
++#ifdef DEBUG	
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_L_UR_FLAG | I2S_TXBF_L_EMPTY_FLAG);
++#else
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG | I2S_TXBF_R_EMPTY_FLAG | I2S_TXBF_L_EMPTY_FLAG);
++#endif
++#endif //CONFIG_I2S_USE_DMA
++
++	// Enable CPU interrupt
++	local_irq_enable();
++	
++#ifdef CONFIG_I2S_USE_DMA
++	/*
++	 * Note DMA must be enabled first before I2S is enabled
++	 */
++	HAL_DMAC_ENABLE();
++#endif //CONFIG_I2S_USE_DMA
++	HAL_I2S_ENABLE_I2S();
++
++
++	while (1){
++		local_irq_disable();
++		if (lpos>llen||llen==0){
++			// Disable I2S
++			HAL_I2S_DISABLE_I2S();
++			break;
++		}
++		local_irq_enable();
++	}
++	DEBUG_PRINT("%s: exit. i2s_err_lur=%d\n",__FUNCTION__,i2s_err_lur);
++
++	local_irq_enable();
++
++	return len;
++
++debug:
++	HAL_I2S_DISABLE_I2S();
++	return count;
++}
++
++static void __exit i2s_exit_module(void){
++	printk("%s:\n",__FUNCTION__);
++	remove_proc_entry("str8100/i2s", NULL);
++	free_irq(INTC_I2S_BIT_INDEX, NULL);
++#ifdef CONFIG_I2S_USE_DMA
++	free_irq(INTC_GDMAC_TC_BIT_INDEX, NULL);
++	free_irq(INTC_GDMAC_ERROR_BIT_INDEX, NULL);
++#endif //CONFIG_I2S_USE_DMA
++	if(lbuffer) {
++		pci_free_consistent(NULL, BUFSIZE, lbuffer, lbuffer_p);
++		lbuffer=lbuffer_p=NULL;
++	}
++}
++
++static int __init i2s_init_module(void)
++{
++	
++	u32 ret;
++	
++	printk("%s:\n",__FUNCTION__);
++#ifdef CONFIG_I2S_USE_DMA
++	printk("%s: DMA Enabled...\n",__FUNCTION__);
++#endif //CONFIG_I2S_USE_DMA
++
++	star_i2s_proc_entry = create_proc_entry("str8100/i2s", S_IFREG | S_IRUGO, NULL);
++	if(!star_i2s_proc_entry){
++		return -EBUSY;
++	}
++	star_i2s_proc_entry->read_proc=proc_read_i2s;
++	star_i2s_proc_entry->write_proc=proc_write_i2s;
++	
++	lbuffer = pci_alloc_consistent(NULL, BUFSIZE, &lbuffer_p);
++	if(!lbuffer){
++		printk("%s: alloc lbuffer failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++
++	str8100_set_interrupt_trigger (INTC_I2S_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_LOW);
++	if ((ret=request_irq(INTC_I2S_BIT_INDEX, str8100_i2s_irq_handler, 0, "i2s", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_I2S_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++
++#ifdef CONFIG_I2S_USE_DMA
++	str8100_set_interrupt_trigger (INTC_GDMAC_TC_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_TC_BIT_INDEX, str8100_dma_tc_irq_handler, 0, "dma tc", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_TC_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++	str8100_set_interrupt_trigger (INTC_GDMAC_ERROR_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_ERROR_BIT_INDEX, str8100_dma_err_irq_handler, 0, "dma error", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_ERROR_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++#endif //CONFIG_I2S_USE_DMA
++
++	return 0;
++exit1:
++	i2s_exit_module();
++	return -EBUSY;
++}
++
++module_init(i2s_init_module);
++module_exit(i2s_exit_module);
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_i2s_wm8772_config.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_i2s_wm8772_config.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_i2s_wm8772_config.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_i2s_wm8772_config.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,924 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++//Options
++#define DEBUG
++#define I2S_FULL_DUPLEX
++#define I2S_WM8772_DMAC_LLP_TEST
++#define I2S_WM8772_DMAC_LLP_NUM      3
++#define I2S_WM8772_BUFFER_SIZE       (48 * 1 * 2 * 100)
++#define I2S_TIMING 	I2S_I2S_MODE
++//#define I2S_TIMING 	I2S_RJF_MODE
++//#define I2S_TIMING 	I2S_LJF_MODE
++#define DATA_WIDTH 	I2S_DATA_32_BIT
++//#define DATA_WIDTH 	I2S_DATA_16_BIT
++#define I2S_MODE 	I2S_MASTER_MODE
++//#define I2S_MODE 	I2S_SLAVE_MODE
++#define I2S_SCLK_MODE	I2S_CLOCK_256S_MODE
++//#define I2S_SCLK_MODE	I2S_CLOCK_CONTINUOUS_MODE
++//*******************
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++
++#include <linux/kernel.h>	/* printk() */
++#include <linux/errno.h>	/* error codes */
++#include <linux/types.h>	/* size_t */
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++#include <linux/pci.h>
++
++#include <asm/system.h>		/* cli(), *_flags */
++#include <asm/uaccess.h>	/* copy_*_user */
++
++#include <mach/star_powermgt.h>
++#include <mach/star_misc.h>
++#include <mach/star_i2s.h>
++#include <mach/star_demo_dma.h>
++
++MODULE_AUTHOR("Mac Lin");
++MODULE_LICENSE("Dual BSD/GPL");
++
++
++//Debug = left only
++
++static u32 sampling_rate=44100;
++
++module_param(sampling_rate, int, 0);
++MODULE_PARM_DESC(gpio, "sampling_rate");
++
++//#define DMA_TRANSFER_MAX_BYTE    (0xfff<<(sample_size>>4)) 
++//#define BUFSIZE (0xfff<<4) //twice the 32-bit DMA transfer byte size
++
++static u8* buffer=NULL;
++static u8* buffer_p=NULL;
++static DMAC_LLP_T* desc=NULL;
++static DMAC_LLP_T* desc_p=NULL;
++
++static u8* lbuffer=NULL;
++static u8* lbuffer_p=NULL;
++static DMAC_LLP_T* lb_txd=NULL;
++static DMAC_LLP_T* lb_txd_p=NULL;
++static DMAC_LLP_T* lb_rxd=NULL;
++static DMAC_LLP_T* lb_rxd_p=NULL;
++
++static u8* rbuffer=NULL;
++static u8* rbuffer_p=NULL;
++static DMAC_LLP_T* rb_txd=NULL;
++static DMAC_LLP_T* rb_txd_p=NULL;
++static DMAC_LLP_T* rb_rxd=NULL;
++static DMAC_LLP_T* rb_rxd_p=NULL;
++
++static DMAC_LLP_T* i2s_left_tx_channel_dma_llp_desc=NULL;
++static DMAC_LLP_T* i2s_left_rx_channel_dma_llp_desc=NULL;
++static DMAC_LLP_T* i2s_right_tx_channel_dma_llp_desc=NULL;
++static DMAC_LLP_T* i2s_right_rx_channel_dma_llp_desc=NULL;
++
++static u8* i2s_left_channel_llp_buf[I2S_WM8772_DMAC_LLP_NUM];
++static u8* i2s_right_channel_llp_buf[I2S_WM8772_DMAC_LLP_NUM];
++
++
++static u32 i2s_err_lur=0;
++
++static u32 debug=0;
++#define DEBUG_PRINT(arg...) if(debug) printk(arg);
++
++static u32 i2s_wm8772_dma_left_tx_channel 	= 0;
++static u32 i2s_wm8772_dma_right_tx_channel 	= 1;
++static u32 i2s_wm8772_dma_left_rx_channel 	= 2;
++static u32 i2s_wm8772_dma_right_rx_channel 	= 3;
++
++
++#if (I2S_WM8772_DMAC_LLP_NUM >= 3)
++#define I2S_WM8772_DMAC_LLP_RING_TEST
++#endif
++#define BUFSIZE (I2S_WM8772_DMAC_LLP_NUM*I2S_WM8772_BUFFER_SIZE*4)
++
++#define I2S_BASE_ADDR SYSPA_I2S_BASE_ADDR
++#define i2s_dmac_llp_num I2S_WM8772_DMAC_LLP_NUM
++//=================================================================================
++//
++
++/******************************************************************************
++ *
++ * FUNCTION:  I2s_Configure_WM8772
++ * PURPOSE:
++ *
++ ******************************************************************************/
++void I2s_Configure_WM8772(u32 interface_format, u32 word_length, u32 data_interface_mode)
++{
++    u16    reg_data;
++
++
++    /*
++     * The current configuration of W571C161 DAC are:
++     * 1. MODE : External hardware setting control mode
++     * 2. COM1 = 1, COM2 = 0 : 16-bit I2S
++     * 3. COM3 = 0 : De-emphasis filter off
++     * 4. I2S Level 2 (Slave Mode) : How to configure it
++     */
++
++    /*
++     * Configure register R31 for reset
++     */
++#if 1
++    reg_data = (0x1F << 9) |  /* Register address value : 0x1F */
++               (0x1FF);
++#else
++    reg_data = (0xF << 9) |  /* Register address value : 0xF */
++               (0x1FF);
++#endif
++
++    I2s_Gpio_SSP_Write(reg_data);
++    
++    /*
++     * Configure register R2
++     */ 
++    reg_data = (0x2 << 9) |  /* Register address value : 0x2 */
++#if 1
++//               (0x5 << 5) |  /* Right Channel Output Mixer Status : right channel data */
++               (0x9 << 5) |  /* Right Channel Output Mixer Status : right channel data */
++                             /* Left Channel Output Mixer Status : left channel data */
++#else
++               (0x2 << 7) |  /* Right Channel Output Mixer Status : right channel data */
++               (0x1 << 5) |  /* Left Channel Output Mixer Status : left channel data */
++#endif
++               (0x0 << 4) |  /* IZM : disable */
++               (0x0 << 3) |  /* ATC : right channels use right attenuations */
++               (0x0 << 2) |  /* PDWNALL : disable */
++               (0x0 << 1) |  /* DEEMPALL : normal */
++               (0x0 << 0);   /* Soft Mute Select : normal */
++
++    I2s_Gpio_SSP_Write(reg_data);
++ 
++    /*
++     * Configure register R12
++     */
++    reg_data = (0xC << 9) |  /* Register address value : 0xC */
++               (0x1 << 6) |  /* Disable the MUTE decoded circuit used by DZFM */
++//               (0x0 << 6) |  /* Enable the MUTE decoded circuit used by DZFM */
++               (0x0 << 2) |  /* Normal operation */
++               (0x0 << 1) |  /* Normal operation */
++               (0x0 << 0);   /* Normal operation */
++
++    I2s_Gpio_SSP_Write(reg_data);
++
++    
++    /*
++     * Configure register R9
++     */
++    reg_data = (0x9 << 9) |  /* Register address value : 0x9 */
++               (0x0 << 8) |  /* Channel 3L/R De-emphasis Status : No de-emphasis */
++               (0x0 << 7) |  /* Channel 2L/R De-emphasis Status : No de-emphasis */
++               (0x0 << 6) |  /* Channel 1L/R De-emphasis Status : No de-emphasis */
++               (0x1 << 5) |  /* Channel 3L/R Play Status : Mute */
++               (0x1 << 4) |  /* Channel 2L/R Play Status : Mute */
++               (0x0 << 3) |  /* Channel 1L/R Play Status : play */
++               (0x3 << 1) |  /* DZFM[1:0] : Channel 3 */
++               (0x1 << 0);   /* ZCD : disabled */
++
++    I2s_Gpio_SSP_Write(reg_data);
++
++
++    /*
++     * Configure register R3 for audio data interface format
++     */
++    reg_data = (0x3 << 9) |  /* Register address value : 0x3 */
++               (0x0 << 6) |  /* Phase : normal */
++               (0x0 << 4) |  /* Input Word Length : 16-bit(0x0 << 4) ; 32-bit(0x3 <<4) */
++#if 0
++               (0x1 << 3) |  /* BCK Polarity : invert : for DSP mode only ????? */
++#else
++               (0x0 << 3) |  /* BCK Polarity : normal */
++#endif
++
++#if 0
++               (0x1 << 2) |  /* LRC Polarity : invert */
++#else
++               (0x0 << 2) |  /* LRC Polarity : normal */
++#endif          
++               (0x0 << 0);   /* Interface Format : right justified mode */
++
++    if (interface_format == I2S_RJF_MODE)
++    {
++        reg_data |= 0;
++    }
++    else if (interface_format == I2S_LJF_MODE)
++    {
++        reg_data |= 1;
++    }
++    else if (interface_format == I2S_I2S_MODE)
++    {
++        reg_data |= 2;
++    }
++    else
++    {
++        printk("\nI2S: Incorrect selected interface mode: DSP mode!\n");
++        
++        reg_data |= 3;
++    }
++
++    /*
++     *  16-bit data for I2S_RJF_MODE
++     */ 
++    if (interface_format == I2S_RJF_MODE)
++    {
++        // 16-bit data
++        reg_data |= (0 << 4);
++    }
++    else
++    {
++        if (word_length == I2S_DATA_16_BIT)
++        {
++            reg_data |= (0 << 4);
++        }
++        else if (word_length == I2S_DATA_32_BIT)
++        {
++            reg_data |= (3 << 4);
++        }
++    }
++
++    I2s_Gpio_SSP_Write(reg_data);
++
++    
++    /*
++     * Configure register R10
++     */
++    reg_data = (0xA << 9) |  /* Register address value : 0xA */
++               (0x2 << 6) |  /* Frequency Ratio = MCLK/LRC : 256 */
++               //(0x3 << 6) |  /* Frequency Ratio = MCLK/LRC : 384 */
++               //(0x0 << 6) |  /* Frequency Ratio = MCLK/LRC : 128 */
++               (0x0 << 5) |  /* Data Interface Mode : Level 2 (Slave mode) */
++               (0x0 << 4) |  /* All Channel Power Down : play */
++               (0x1 << 3) |  /* Channel 3 L/R Play Status : power down */
++               (0x1 << 2) |  /* Channel 2 L/R Play Status : power down */
++               (0x0 << 1) |  /* Channel 1 L/R Play Status : play */
++#if 0
++               (0x1 << 0);   /* ADC deactive */
++#else
++               (0x0 << 0);   /* ADC active */
++#endif
++
++    if (data_interface_mode == I2S_SLAVE_MODE)
++    {
++        /*
++         * Equuleus's I2S is in Slave mode, so WM8772 will be in Master mode
++         */
++        reg_data |= (0x1 << 5);
++    }
++
++    I2s_Gpio_SSP_Write(reg_data);
++
++
++    /*
++     * Configure register R11?????
++     */
++    reg_data = (0xB << 9) |  /* Register address value : 0xB */
++               (0x0 << 8);   /* 128x oversampling */
++               
++    I2s_Gpio_SSP_Write(reg_data);
++
++
++    /*
++     * Configure register R12
++     */
++    reg_data = (0xC << 9) |  /* Register address value : 0xC */
++               (0x0 << 3);   /* Highpass filter enabled */
++               
++    I2s_Gpio_SSP_Write(reg_data);
++    
++    return;
++}
++
++//=================================================================================
++//
++
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8772_dma_right_tx;
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8772_dma_right_rx;
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8772_dma_left_tx;
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8772_dma_left_rx;
++
++void I2s_Configure_WM8772_DMA_Hardware_Handshake(void)
++{
++	u32 ii,tot_size;
++    /*
++     * Initialize DMAC's LLP descriptors
++     */
++	i2s_left_tx_channel_dma_llp_desc=lb_txd;
++	i2s_left_rx_channel_dma_llp_desc=lb_rxd;
++	i2s_right_tx_channel_dma_llp_desc=rb_txd;
++	i2s_right_rx_channel_dma_llp_desc=rb_rxd;
++	
++    for (ii = 0; ii < I2S_WM8772_DMAC_LLP_NUM; ii++)
++    {
++        memset ((void *)&i2s_left_tx_channel_dma_llp_desc[ii], 0x0, sizeof (i2s_left_tx_channel_dma_llp_desc[ii]));
++        memset ((void *)&i2s_left_rx_channel_dma_llp_desc[ii], 0x0, sizeof (i2s_left_rx_channel_dma_llp_desc[ii]));
++        
++        memset ((void *)&i2s_right_tx_channel_dma_llp_desc[ii], 0x0, sizeof (i2s_right_tx_channel_dma_llp_desc[ii]));
++        memset ((void *)&i2s_right_rx_channel_dma_llp_desc[ii], 0x0, sizeof (i2s_right_rx_channel_dma_llp_desc[ii]));
++    }
++
++//1. *****************************************************************************
++    /*
++     * Configure DMA's channel setting for I2S's Left Channel Tx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    for (ii = 0; ii < I2S_WM8772_DMAC_LLP_NUM; ii++)
++    {
++        i2s_left_tx_channel_dma_llp_desc[ii].SrcAddr = i2s_left_channel_llp_buf[ii];
++        
++        i2s_left_tx_channel_dma_llp_desc[ii].DstAddr = (I2S_BASE_ADDR + 0xC8);
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_left_tx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&lb_txd_p[ii+1] : (DMAC_LLP_T *)&lb_txd_p[1];
++#else
++        i2s_left_tx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&lb_txd_p[ii+1] : (DMAC_LLP_T *)(0);
++#endif
++
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++        
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.tot_size = tot_size;  /* TOT_SIZE */
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_sel = DMAC_CH_DST_SEL_M0;  /* DST_SEL */
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_sel = DMAC_CH_SRC_SEL_M1;  /* SRC_SEL */
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;  /* DSTAD_CTL */
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;  /* SRCAD_CTL */
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_width = DMAC_CH_DST_WIDTH_32_BITS;  /* DST_WIDTH */
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_width = DMAC_CH_SRC_WIDTH_32_BITS;  /* SRC_WIDTH */       
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = (DMAC_CH_TC_MASK_ENABLE);  /* TC_MASK */
++#else
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = ((ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_CH_TC_MASK_ENABLE) : (DMAC_CH_TC_MASK_DISABLE));  /* TC_MASK */
++#endif
++    }
++
++    i2s_wm8772_dma_left_tx.channel_id = DMAC_CH_ID(i2s_wm8772_dma_left_tx_channel);
++    i2s_wm8772_dma_left_tx.target_select = DMAC_HW_HAND_SHAKE_I2S_TX_LEFT_ID;
++
++    i2s_wm8772_dma_left_tx.src_addr = i2s_left_tx_channel_dma_llp_desc[0].SrcAddr;
++    i2s_wm8772_dma_left_tx.dst_addr = i2s_left_tx_channel_dma_llp_desc[0].DstAddr;
++
++    i2s_wm8772_dma_left_tx.src_master = DMAC_CH_SRC_SEL_M1;
++    i2s_wm8772_dma_left_tx.dst_master = DMAC_CH_DST_SEL_M0;
++
++    i2s_wm8772_dma_left_tx.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;
++    i2s_wm8772_dma_left_tx.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;
++
++    i2s_wm8772_dma_left_tx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    i2s_wm8772_dma_left_tx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++
++    // Note here the total number of bytes is specified!!
++    i2s_wm8772_dma_left_tx.transfer_bytes = I2S_WM8772_BUFFER_SIZE * 4;
++
++    i2s_wm8772_dma_left_tx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;   
++
++    i2s_wm8772_dma_left_tx.llp_addr = (i2s_dmac_llp_num == 1) ? 0 : (u32)i2s_left_tx_channel_dma_llp_desc[0].LLP;
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8772_dma_left_tx);
++//2. *****************************************************************************
++    /*
++     * Configure DMA's channel setting for I2S's Right Channel Tx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    for (ii = 0; ii < I2S_WM8772_DMAC_LLP_NUM; ii++)
++    {
++        i2s_right_tx_channel_dma_llp_desc[ii].SrcAddr = i2s_right_channel_llp_buf[ii];
++        
++        i2s_right_tx_channel_dma_llp_desc[ii].DstAddr = (I2S_BASE_ADDR + 0xC4);
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_right_tx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&rb_txd_p[ii+1] : (DMAC_LLP_T *)&rb_txd_p[1];
++#else
++        i2s_right_tx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&rb_txd_p[ii + 1] : (DMAC_LLP_T *)(0);
++#endif
++
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.tot_size = tot_size;  /* TOT_SIZE */
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_sel = DMAC_CH_DST_SEL_M0;  /* DST_SEL */
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_sel = DMAC_CH_SRC_SEL_M1;  /* SRC_SEL */
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;  /* DSTAD_CTL */
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;  /* SRCAD_CTL */
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_width = DMAC_CH_DST_WIDTH_32_BITS;  /* DST_WIDTH */
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_width = DMAC_CH_SRC_WIDTH_32_BITS;  /* SRC_WIDTH */
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = (DMAC_CH_TC_MASK_ENABLE);  /* TC_MASK */
++#else
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = ((ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_CH_TC_MASK_ENABLE) : (DMAC_CH_TC_MASK_DISABLE));  /* TC_MASK */
++#endif
++    }
++
++
++    i2s_wm8772_dma_right_tx.channel_id = DMAC_CH_ID(i2s_wm8772_dma_right_tx_channel);
++    i2s_wm8772_dma_right_tx.target_select = DMAC_HW_HAND_SHAKE_I2S_TX_RIGHT_ID;
++
++    i2s_wm8772_dma_right_tx.src_addr = i2s_right_tx_channel_dma_llp_desc[0].SrcAddr;
++    i2s_wm8772_dma_right_tx.dst_addr = i2s_right_tx_channel_dma_llp_desc[0].DstAddr;
++
++    i2s_wm8772_dma_right_tx.src_master = DMAC_CH_SRC_SEL_M1;
++    i2s_wm8772_dma_right_tx.dst_master = DMAC_CH_DST_SEL_M0;
++
++    i2s_wm8772_dma_right_tx.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;
++    i2s_wm8772_dma_right_tx.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;
++
++    i2s_wm8772_dma_right_tx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    i2s_wm8772_dma_right_tx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    // Note here the total number of bytes is specified!!
++    i2s_wm8772_dma_right_tx.transfer_bytes = I2S_WM8772_BUFFER_SIZE * 4;
++
++    i2s_wm8772_dma_right_tx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;
++
++    i2s_wm8772_dma_right_tx.llp_addr = (i2s_dmac_llp_num == 1) ? 0 : (u32)i2s_right_tx_channel_dma_llp_desc[0].LLP;
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8772_dma_right_tx);
++
++
++//3. *****************************************************************************
++    /*
++     * Configure DMA's channel setting for I2S's Left Channel Rx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    for (ii = 0; ii < I2S_WM8772_DMAC_LLP_NUM; ii++)
++    {
++        i2s_left_rx_channel_dma_llp_desc[ii].SrcAddr = (I2S_BASE_ADDR + 0xD0);
++        
++        i2s_left_rx_channel_dma_llp_desc[ii].DstAddr = i2s_left_channel_llp_buf[ii];
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_left_rx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&lb_rxd_p[ii + 1] : (DMAC_LLP_T *)&lb_rxd_p[1];
++#else
++        i2s_left_rx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&lb_rxd_p[ii + 1] : (DMAC_LLP_T *)(0);
++#endif
++
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.tot_size = tot_size;  /* TOT_SIZE */
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_sel = DMAC_CH_DST_SEL_M1;  /* DST_SEL */
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_sel = DMAC_CH_SRC_SEL_M0;  /* SRC_SEL */
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.dstad_ctl = DMAC_CH_DSTAD_CTL_INC;  /* DSTAD_CTL */
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.srcad_ctl = DMAC_CH_SRCAD_CTL_FIX;  /* SRCAD_CTL */
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_width = DMAC_CH_DST_WIDTH_32_BITS;  /* DST_WIDTH */
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_width = DMAC_CH_SRC_WIDTH_32_BITS;  /* SRC_WIDTH */
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = (DMAC_CH_TC_MASK_ENABLE);  /* TC_MASK */
++#else
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = ((ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_CH_TC_MASK_ENABLE) : (DMAC_CH_TC_MASK_DISABLE));  /* TC_MASK */
++#endif
++    }
++
++    i2s_wm8772_dma_left_rx.channel_id = DMAC_CH_ID(i2s_wm8772_dma_left_rx_channel);
++    i2s_wm8772_dma_left_rx.target_select = DMAC_HW_HAND_SHAKE_I2S_RX_LEFT_ID;
++
++    i2s_wm8772_dma_left_rx.src_addr = i2s_left_rx_channel_dma_llp_desc[0].SrcAddr;
++    i2s_wm8772_dma_left_rx.dst_addr = i2s_left_rx_channel_dma_llp_desc[0].DstAddr;
++
++    i2s_wm8772_dma_left_rx.src_master = DMAC_CH_SRC_SEL_M0;
++    i2s_wm8772_dma_left_rx.dst_master = DMAC_CH_DST_SEL_M1;
++
++    i2s_wm8772_dma_left_rx.srcad_ctl = DMAC_CH_SRCAD_CTL_FIX;
++    i2s_wm8772_dma_left_rx.dstad_ctl = DMAC_CH_DSTAD_CTL_INC;
++
++    i2s_wm8772_dma_left_rx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    i2s_wm8772_dma_left_rx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    // Note here the total number of bytes is specified!!
++    i2s_wm8772_dma_left_rx.transfer_bytes = I2S_WM8772_BUFFER_SIZE * 4;
++
++    i2s_wm8772_dma_left_rx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;   
++
++    i2s_wm8772_dma_left_rx.llp_addr = (i2s_dmac_llp_num == 1) ? 0 : (u32)i2s_left_rx_channel_dma_llp_desc[0].LLP;
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8772_dma_left_rx);
++
++//4. *****************************************************************************
++    /*
++     * Configure DMA's channel setting for I2S's Right Channel Rx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    for (ii = 0; ii < I2S_WM8772_DMAC_LLP_NUM; ii++)
++    {
++        i2s_right_rx_channel_dma_llp_desc[ii].SrcAddr = (I2S_BASE_ADDR + 0xCC);
++        
++        i2s_right_rx_channel_dma_llp_desc[ii].DstAddr = i2s_right_channel_llp_buf[ii];
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_right_rx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&rb_rxd_p[ii + 1] : (DMAC_LLP_T *)&rb_rxd_p[1];
++#else
++        i2s_right_rx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&rb_rxd_p[ii + 1] : (DMAC_LLP_T *)(0);
++#endif
++
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.tot_size = tot_size;  /* TOT_SIZE */
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_sel = DMAC_CH_DST_SEL_M1;  /* DST_SEL */
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_sel = DMAC_CH_SRC_SEL_M0;  /* SRC_SEL */
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.dstad_ctl = DMAC_CH_DSTAD_CTL_INC;  /* DSTAD_CTL */
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.srcad_ctl = DMAC_CH_SRCAD_CTL_FIX;  /* SRCAD_CTL */
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_width = DMAC_CH_DST_WIDTH_32_BITS;  /* DST_WIDTH */
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_width = DMAC_CH_SRC_WIDTH_32_BITS;  /* SRC_WIDTH */
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = (DMAC_CH_TC_MASK_ENABLE);  /* TC_MASK */
++#else
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = ((ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_CH_TC_MASK_ENABLE) : (DMAC_CH_TC_MASK_DISABLE));  /* TC_MASK */
++#endif
++    }
++
++    i2s_wm8772_dma_right_rx.channel_id = DMAC_CH_ID(i2s_wm8772_dma_right_rx_channel);
++    i2s_wm8772_dma_right_rx.target_select = DMAC_HW_HAND_SHAKE_I2S_RX_RIGHT_ID;
++
++    i2s_wm8772_dma_right_rx.src_addr = i2s_right_rx_channel_dma_llp_desc[0].SrcAddr;
++    i2s_wm8772_dma_right_rx.dst_addr = i2s_right_rx_channel_dma_llp_desc[0].DstAddr;
++
++    i2s_wm8772_dma_right_rx.src_master = DMAC_CH_SRC_SEL_M0;
++    i2s_wm8772_dma_right_rx.dst_master = DMAC_CH_DST_SEL_M1;
++
++    i2s_wm8772_dma_right_rx.srcad_ctl = DMAC_CH_SRCAD_CTL_FIX;
++    i2s_wm8772_dma_right_rx.dstad_ctl = DMAC_CH_DSTAD_CTL_INC;
++
++    i2s_wm8772_dma_right_rx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    i2s_wm8772_dma_right_rx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    // Note here the total number of bytes is specified!!
++    i2s_wm8772_dma_right_rx.transfer_bytes = I2S_WM8772_BUFFER_SIZE * 4;
++
++    i2s_wm8772_dma_right_rx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;
++
++    i2s_wm8772_dma_right_rx.llp_addr = (i2s_dmac_llp_num == 1) ? 0 : (u32)i2s_right_rx_channel_dma_llp_desc[0].LLP;
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8772_dma_right_rx);
++//*****************************************************************************
++    return;
++}
++
++
++//=================================================================================
++//
++
++extern void str8100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++
++static irqreturn_t str8100_dma_tc_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 dma_tc_status,tot_size;
++	u32 len;
++//printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++
++    HAL_DMAC_READ_TERMINAL_COUNT_INTERRUPT_STATUS(dma_tc_status);
++printk("%s: this_irq=%d, dma_tc_status=%.8x\n",__FUNCTION__,this_irq,dma_tc_status);
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++	u32 i;
++    /*
++     * For LLP ring test, the TC interrupt shoule not happen!!
++     */
++	for(i=0;i<8;i++)
++	if (dma_tc_status & DMAC_CH_ID(i)){                      
++		HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i));
++		printk("%s: channel %d: Error!! there should be no tc irq happened!!\n",__FUNCTION__,i);
++	}
++
++#else
++    /*
++     * For this case, it's recommended to set I2S_WM8772_DMAC_LLP_NUM = 1
++     */
++    /*
++     * For DMA's Tx for I2S Left Channel
++     */
++    if (dma_tc_status & DMAC_CH_ID(i2s_wm8772_dma_left_tx_channel))
++    {                      
++        HAL_DMAC_DISABLE_CHANNEL(i2s_wm8772_dma_left_tx_channel);
++        
++        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8772_dma_left_tx_channel));
++
++        /*
++         * Re-initialize DMA's channel for Left_Tx
++         */
++        DMAC_CH_SRC_ADDR(i2s_wm8772_dma_left_tx_channel) = i2s_left_tx_channel_dma_llp_desc[0].SrcAddr;
++
++        DMAC_CH_DST_ADDR(i2s_wm8772_dma_left_tx_channel) = i2s_left_tx_channel_dma_llp_desc[0].DstAddr;
++
++        /*
++         * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
++         * number of source transfer width!
++         */        
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++
++        DMAC_CH_SIZE(i2s_wm8772_dma_left_tx_channel) = tot_size & 0x0FFF;
++
++        HAL_DMAC_ENABLE_CHANNEL(i2s_wm8772_dma_left_tx_channel);
++    }
++
++
++    /*
++     * For DMA's Tx for I2S Right Channel
++     */
++    if (dma_tc_status & DMAC_CH_ID(i2s_wm8772_dma_right_tx_channel))
++    {                      
++        HAL_DMAC_DISABLE_CHANNEL(i2s_wm8772_dma_right_tx_channel);
++        
++        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8772_dma_right_tx_channel));
++
++        /*
++         * Re-initialize DMA's channel for Right_Tx
++         */
++        DMAC_CH_SRC_ADDR(i2s_wm8772_dma_right_tx_channel) = i2s_right_tx_channel_dma_llp_desc[0].SrcAddr;
++
++        DMAC_CH_DST_ADDR(i2s_wm8772_dma_right_tx_channel) = i2s_right_tx_channel_dma_llp_desc[0].DstAddr;
++
++        /*
++         * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
++         * number of source transfer width!
++         */        
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++
++        DMAC_CH_SIZE(i2s_wm8772_dma_right_tx_channel) = tot_size & 0x0FFF;
++
++        HAL_DMAC_ENABLE_CHANNEL(i2s_wm8772_dma_right_tx_channel);
++    }
++
++
++    /*
++     * For DMA's Rx for I2S Left Channel
++     */
++    if (dma_tc_status & DMAC_CH_ID(i2s_wm8772_dma_left_rx_channel))
++    {                      
++        HAL_DMAC_DISABLE_CHANNEL(i2s_wm8772_dma_left_rx_channel);
++        
++        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8772_dma_left_rx_channel));
++
++        /*
++         * Re-initialize DMA's channel for Left_Rx
++         */
++        DMAC_CH_SRC_ADDR(i2s_wm8772_dma_left_rx_channel) = i2s_left_rx_channel_dma_llp_desc[0].SrcAddr;
++
++        DMAC_CH_DST_ADDR(i2s_wm8772_dma_left_rx_channel) = i2s_left_rx_channel_dma_llp_desc[0].DstAddr;
++
++        /*
++         * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
++         * number of source transfer width!
++         */        
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++
++        DMAC_CH_SIZE(i2s_wm8772_dma_left_rx_channel) = tot_size & 0x0FFF;
++
++        HAL_DMAC_ENABLE_CHANNEL(i2s_wm8772_dma_left_rx_channel);
++    }
++
++
++    /*
++     * For DMA's Rx for I2S Right Channel
++     */
++    if (dma_tc_status & DMAC_CH_ID(i2s_wm8772_dma_right_rx_channel))
++    {                      
++        HAL_DMAC_DISABLE_CHANNEL(i2s_wm8772_dma_right_rx_channel);
++        
++        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8772_dma_right_rx_channel));
++
++        /*
++         * Re-initialize DMA's channel for Right_Rx
++         */
++        DMAC_CH_SRC_ADDR(i2s_wm8772_dma_right_rx_channel) = i2s_right_rx_channel_dma_llp_desc[0].SrcAddr;
++
++        DMAC_CH_DST_ADDR(i2s_wm8772_dma_right_rx_channel) = i2s_right_rx_channel_dma_llp_desc[0].DstAddr;
++
++        /*
++         * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
++         * number of source transfer width!
++         */        
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++
++        DMAC_CH_SIZE(i2s_wm8772_dma_right_rx_channel) = tot_size & 0x0FFF;
++
++        HAL_DMAC_ENABLE_CHANNEL(i2s_wm8772_dma_right_rx_channel);
++    }
++#endif
++
++
++
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++
++static irqreturn_t str8100_i2s_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 interrupt_status;
++	DEBUG_PRINT("%s: this_irq=%d, I2S_INTERRUPT_STATUS_REG=0x%.8x\n",__FUNCTION__,this_irq,I2S_INTERRUPT_STATUS_REG);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++	interrupt_status = I2S_INTERRUPT_STATUS_REG;   
++
++		I2S_RIGHT_TRANSMIT_DATA_REG=0;
++
++
++	if ((interrupt_status & (I2S_RXBF_R_FULL_FLAG | I2S_RXBF_L_FULL_FLAG | I2S_TXBF_R_EMPTY_FLAG | I2S_TXBF_L_EMPTY_FLAG))){
++		printk("%s: Error! wrong i2s empty/full flag\n",__FUNCTION__);
++	
++	}
++
++	if ((interrupt_status & (I2S_RXBF_R_OR_FLAG | I2S_RXBF_L_OR_FLAG |I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG))){
++		// Clear I2S interrupt status
++		i2s_err_lur++;
++		if(i2s_err_lur>10)
++			I2S_INTERRUPT_ENABLE_REG &= ~(I2S_TXBF_L_UR_FLAG);
++//			HAL_I2S_DISABLE_I2S();
++		
++		printk("%s: Left Channel Tx Underrun!, interrupt_status=%.8x,i2s_err_lur=%d\n",__FUNCTION__,interrupt_status,i2s_err_lur);
++	}
++	I2S_INTERRUPT_STATUS_REG &= 0xf0;
++
++	
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++
++
++//=================================================================================
++
++static void i2s_exit_module(void){
++	printk("%s:\n",__FUNCTION__);
++	remove_proc_entry("str8100/i2s", NULL);
++	free_irq(INTC_I2S_BIT_INDEX, NULL);
++	free_irq(INTC_GDMAC_TC_BIT_INDEX, NULL);
++	free_irq(INTC_GDMAC_ERROR_BIT_INDEX, NULL);
++	if(buffer) {
++		pci_free_consistent(NULL, BUFSIZE*2, buffer, buffer_p);
++		buffer=buffer_p=NULL;
++		lbuffer=lbuffer_p=rbuffer=rbuffer_p=NULL;
++	}
++	if(desc) {
++		pci_free_consistent(NULL, I2S_WM8772_DMAC_LLP_NUM*sizeof(DMAC_LLP_T)*4 , desc, desc_p);
++		desc=desc_p=NULL;
++		lb_txd=lb_txd_p=lb_rxd=lb_rxd_p=NULL;
++		rb_txd=rb_txd_p=rb_rxd=rb_rxd_p=NULL;
++	}
++}
++
++static int __init i2s_init_module(void)
++{
++	
++	u32 ret;
++	u32 ii;
++	
++	printk("%s:\n",__FUNCTION__);
++
++	buffer = pci_alloc_consistent(NULL, BUFSIZE*2, &buffer_p);
++	if(!buffer){
++		printk("%s: alloc buffer failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++	lbuffer=buffer;
++	lbuffer_p=buffer_p;
++	rbuffer=lbuffer+BUFSIZE;
++	rbuffer_p=lbuffer_p+BUFSIZE;
++	
++	desc = pci_alloc_consistent(NULL, I2S_WM8772_DMAC_LLP_NUM*sizeof(DMAC_LLP_T)*4 , &desc_p);
++	if(!desc){
++		printk("%s: alloc buffer for desc failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++	lb_txd=desc;
++	lb_txd_p=desc_p;
++	lb_rxd=desc+I2S_WM8772_DMAC_LLP_NUM;
++	lb_rxd_p=desc_p+I2S_WM8772_DMAC_LLP_NUM;
++
++	rb_txd=desc+I2S_WM8772_DMAC_LLP_NUM*2;
++	rb_txd_p=desc_p+I2S_WM8772_DMAC_LLP_NUM*2;
++	rb_rxd=desc+I2S_WM8772_DMAC_LLP_NUM*3;
++	rb_rxd_p=desc_p+I2S_WM8772_DMAC_LLP_NUM*3;
++	
++
++	str8100_set_interrupt_trigger (INTC_I2S_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_LOW);
++	if ((ret=request_irq(INTC_I2S_BIT_INDEX, str8100_i2s_irq_handler, 0, "i2s", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_I2S_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++
++	str8100_set_interrupt_trigger (INTC_GDMAC_TC_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_TC_BIT_INDEX, str8100_dma_tc_irq_handler, 0, "dma tc", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_TC_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++	str8100_set_interrupt_trigger (INTC_GDMAC_ERROR_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_ERROR_BIT_INDEX, str8100_dma_err_irq_handler, 0, "dma error", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_ERROR_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++
++	/*
++	 * Initialize GPIO pins for COM1/COM2/COM3
++	 */
++	I2s_Gpio_SSP_Initialise();
++
++	str8100_i2s_init(sampling_rate,DATA_WIDTH, I2S_MODE, I2S_TIMING, I2S_SCLK_MODE);
++
++	/*
++	 * Configure Wolfson's WM8772 ADC/DAC
++	 */
++	I2s_Configure_WM8772(I2S_TIMING, DATA_WIDTH, I2S_MODE); 
++#ifdef I2S_FULL_DUPLEX
++	/*
++	* To support I2S full duplex mode, GPIOA[3] will be used as I2S_DR pin.
++	* It means GPIOA[3] should be as input pin.
++	*/
++	MISC_GPIOA_PIN_ENABLE_REG &= ~(0x1 << 3);
++    
++	GPIOA_DIRECTION_REG &= ~(0x1 << 3);
++#endif
++
++	I2S_RIGHT_TRANSMIT_DATA_REG=0;
++	I2S_LEFT_TRANSMIT_DATA_REG=0;
++	ii=I2S_RIGHT_RECEIVE_DATA_REG;
++	ii=I2S_LEFT_RECEIVE_DATA_REG;
++
++	/*
++	 * Initialize DMAC related configuration
++	 */    
++
++	i2s_left_channel_llp_buf[0] = lbuffer_p;
++	i2s_right_channel_llp_buf[0] = rbuffer_p;
++	memset ((void *)&lbuffer[0], 0x0, I2S_WM8772_BUFFER_SIZE * 4);
++	memset ((void *)&rbuffer[0], 0x0, I2S_WM8772_BUFFER_SIZE * 4);
++	for (ii = 1; ii < I2S_WM8772_DMAC_LLP_NUM; ii++)
++	{
++		i2s_left_channel_llp_buf[ii] = i2s_left_channel_llp_buf[ii - 1] + (I2S_WM8772_BUFFER_SIZE * 4);
++		i2s_right_channel_llp_buf[ii] = i2s_right_channel_llp_buf[ii - 1] + (I2S_WM8772_BUFFER_SIZE * 4);
++		memset ((void *)&lbuffer[ii*I2S_WM8772_BUFFER_SIZE*4], 0x0, I2S_WM8772_BUFFER_SIZE * 4);
++		memset ((void *)&rbuffer[ii*I2S_WM8772_BUFFER_SIZE*4], 0x0, I2S_WM8772_BUFFER_SIZE * 4);
++	}
++
++	i2s_wm8772_dma_left_tx_channel = 0;
++    
++	i2s_wm8772_dma_right_tx_channel = 1;
++    
++	i2s_wm8772_dma_left_rx_channel = 2;
++    
++	i2s_wm8772_dma_right_rx_channel = 3;
++
++
++	I2s_Configure_WM8772_DMA_Hardware_Handshake();
++
++
++	/*
++	 * Enable I2S's interrupt sources
++	 * Note for DMA hardware handshake, we only need to enable Left/Right Channel's 
++	 * Transmit Buffer Underrun.
++	 */
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_RXBF_R_OR_FLAG | I2S_RXBF_L_OR_FLAG | I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG);
++
++	// Enable CPU interrupt
++	local_irq_enable();
++	
++	/*
++	 * Note DMA must be enabled first before I2S is enabled
++	 */
++	HAL_DMAC_ENABLE();
++	HAL_I2S_ENABLE_I2S();
++	printk("%s: exit successfully\n",__FUNCTION__);
++	return 0;
++
++exit1:
++	HAL_I2S_DISABLE_I2S();
++	i2s_exit_module();
++	printk("%s: exit errornous\n",__FUNCTION__);
++	return -EBUSY;
++}
++
++module_init(i2s_init_module);
++module_exit(i2s_exit_module);
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_pcm_legerity_config_2phone.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_pcm_legerity_config_2phone.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_pcm_legerity_config_2phone.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_pcm_legerity_config_2phone.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,921 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++//Options 
++//#define DEBUG_PRINT	
++//=================================================================================
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++
++#include <linux/kernel.h>	/* printk() */
++#include <linux/errno.h>	/* error codes */
++#include <linux/types.h>	/* size_t */
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++#include <linux/pci.h>
++#include <linux/wait.h>		//wait queue
++
++#include <asm/system.h>		/* cli(), *_flags */
++#include <asm/uaccess.h>	/* copy_*_user */
++
++#include <mach/star_spi.h>
++#include <mach/star_pcm.h>
++#include <mach/star_dmac.h>
++#include <mach/star_demo_dma.h>
++
++#include <sound/pcm.h>
++#include <mach/star_i2s.h>
++
++#define u_int32 u32
++#define u_int16 u16
++#define u_int8 u8
++
++extern void Pcm_Initial_Legerity_Le88221(void);
++
++#define Sys_Interrupt_Disable_Save_Flags(_p) local_irq_save(*(_p))
++//#define Sys_Interrupt_Disable_Save_Flags local_irq_save
++#define Sys_Interrupt_Restore_Flags local_irq_restore
++
++#define Hal_Timer_Timer3_Delay(_p) mdelay(_p/1000)
++//int debug = 0;
++#ifdef DEBUG_PRINT
++#undef DEBUG_PRINT
++//#define DEBUG_PRINT(arg...) if(debug) printk(arg);
++#define DEBUG_PRINT printk
++#else
++//#define DEBUG_PRINT(arg...) if(debug) printk(arg);
++#define DEBUG_PRINT(arg...) printk(KERN_DEBUG arg);
++#endif
++
++
++
++/*
++ * public variable declarations
++ */
++PCM_OBJECT_T                          pcm_object;
++PCM_CHANNEL_OBJECT_T                  pcm_channel_object;
++
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T  pcm_tx_data0_dma_legerity;
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T  pcm_rx_data0_dma_legerity;
++//static DMAC_HARDWARE_HANDSHAKE_OBJ_T  pcm_tx_data1_dma_legerity;
++//static DMAC_HARDWARE_HANDSHAKE_OBJ_T  pcm_rx_data1_dma_legerity;
++
++static u_int32                        pcm_tx_data0_dma_channel_num = 2;
++//static u_int32                        pcm_tx_data1_dma_channel_num = 3;
++static u_int32                        pcm_rx_data0_dma_channel_num = 4;
++//static u_int32                        pcm_rx_data1_dma_channel_num = 5;
++
++//#define           BUFFER_SIZE    (1 * 256)
++//#define           BUFFER_SIZE    (1 * 128)
++//#define           BUFFER_SIZE    (1 * PCM_LOG_PERIOD_SEC * 8000)
++#define           BUFFER_SIZE    0xfff
++
++u_int32    *buffer0;
++u_int32    *buffer1;
++u_int32    *buffer2;
++u_int32    *buffer3;
++
++u_int32    *buffer_p0;
++u_int32    *buffer_p1;
++u_int32    *buffer_p2;
++u_int32    *buffer_p3;
++
++u_int32    *pcm_rx0_buffer_le88221;
++u_int32    *pcm_tx0_buffer_le88221;
++u_int32    *pcm_rx1_buffer_le88221;
++u_int32    *pcm_tx1_buffer_le88221;
++
++u_int32    *pcm_rx0_buffer_le88221_p;
++u_int32    *pcm_tx0_buffer_le88221_p;
++u_int32    *pcm_rx1_buffer_le88221_p;
++u_int32    *pcm_tx1_buffer_le88221_p;
++
++
++#define HAL_DMAC_WRITE_CHANNEL0_DESTINATION_ADDRESS(_p) DMAC_CH_DST_ADDR_REG(2) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL1_DESTINATION_ADDRESS(_p) DMAC_CH_DST_ADDR_REG(3) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL2_DESTINATION_ADDRESS(_p) DMAC_CH_DST_ADDR_REG(4) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL3_DESTINATION_ADDRESS(_p) DMAC_CH_DST_ADDR_REG(5) = (_p)
++
++#define HAL_DMAC_WRITE_CHANNEL0_SOURCE_ADDRESS(_p) DMAC_CH_SRC_ADDR_REG(2) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL1_SOURCE_ADDRESS(_p) DMAC_CH_SRC_ADDR_REG(3) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL2_SOURCE_ADDRESS(_p) DMAC_CH_SRC_ADDR_REG(4) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL3_SOURCE_ADDRESS(_p) DMAC_CH_SRC_ADDR_REG(5) = (_p)
++
++#define HAL_DMAC_WRITE_CHANNEL0_TRANSFER_SIZE(_p) DMAC_CH_SIZE_REG(2) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL1_TRANSFER_SIZE(_p) DMAC_CH_SIZE_REG(3) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL2_TRANSFER_SIZE(_p) DMAC_CH_SIZE_REG(4) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL3_TRANSFER_SIZE(_p) DMAC_CH_SIZE_REG(5) = (_p)
++		
++#define HAL_DMAC_ENABLE_CHANNEL0(_p) HAL_DMAC_ENABLE_CHANNEL(2)
++#define HAL_DMAC_ENABLE_CHANNEL1(_p) HAL_DMAC_ENABLE_CHANNEL(3)
++#define HAL_DMAC_ENABLE_CHANNEL2(_p) HAL_DMAC_ENABLE_CHANNEL(4)
++#define HAL_DMAC_ENABLE_CHANNEL3(_p) HAL_DMAC_ENABLE_CHANNEL(5)
++        
++u_int32 rxbuf_full=0;
++u_int32 txbuf_empty=0;
++u_int32 rxbuf_overrun=0;
++u_int32 txbuf_underrun=0;
++
++u_int32 pcm_dma_ch0_tc_count = 0;
++u_int32 pcm_dma_ch2_tc_count = 0;
++u_int32 pcm_dma_ch1_tc_count = 0;
++u_int32 pcm_dma_ch3_tc_count = 0;
++
++/*
++ * For Legerity's Le88221
++ */
++#define        CH0_TX_Le88221_DELAY       (0)
++#define        CH0_RX_Le88221_DELAY       (0)
++
++#define        CH1_TX_Le88221_DELAY       (8)
++#define        CH1_RX_Le88221_DELAY       (8)
++
++#define        CH2_TX_Le88221_DELAY       (32)
++#define        CH2_RX_Le88221_DELAY       (32)
++
++#define        CH3_TX_Le88221_DELAY       (48)
++#define        CH3_RX_Le88221_DELAY       (48)
++
++
++
++
++static struct proc_dir_entry *star_pcm_proc_entry=NULL;
++static u8* txbuffer;
++//static u8* txbuffer_p;
++static u32 txlen=0;
++static u32 txpos=0;
++
++/******************************************************************************
++ *
++ * FUNCTION:  Hal_Pcm_Initialize
++ * PURPOSE:
++ *
++ ******************************************************************************/
++void Hal_Pcm_Initialize(PCM_OBJECT_T *pPcm_Object)
++{
++    //u_int32 volatile    tx_data0 = 0;
++    u_int32 volatile    rx_data0 = 0;
++
++
++    // Enable PCM pins
++    HAL_MISC_ENABLE_PCM_PINS();
++
++    // Enable PCM clock
++    HAL_PWRMGT_ENABLE_PCM_CLOCK(); 
++
++/*    if (p2s_reset_flag == 0)
++    {
++        Hal_Pwrmgt_Software_Reset(PWRMGT_P2S_SOFTWARE_RESET_BIT_INDEX);
++        
++        p2s_reset_flag = 1;
++    }
++*/
++
++    /*
++     * Note PCM is NOT enabled after this function is invoked!!
++     */
++    PCM_CONFIGURATION_0_REG = pPcm_Object->config_0;
++    PCM_CONFIGURATION_1_REG = pPcm_Object->config_1;
++    PCM_CHANNEL_0_CONFIG_REG = pPcm_Object->channel_0_config;
++    PCM_CHANNEL_1_CONFIG_REG = pPcm_Object->channel_1_config;
++    PCM_CHANNEL_2_CONFIG_REG = pPcm_Object->channel_2_config;
++    PCM_CHANNEL_3_CONFIG_REG = pPcm_Object->channel_3_config;
++    PCM_INTERRUPT_ENABLE_REG = pPcm_Object->interrupt_config;
++
++/*
++    if (pPcm_Object->interrupt_config)
++    {
++        Hal_Intc_Register_Interrupt(&pPcm_Object->intc_obj);	
++    }
++*/
++    rx_data0 = PCM_RX_DATA_63_32_REG;
++    rx_data0 = PCM_RX_DATA_31_0_REG;
++
++    // Clear spurious interrupt sources
++    PCM_INTERRUPT_STATUS_REG = PCM_RXBUF_OVERRUN_FG | PCM_TXBUF_UNDERRUN_FG;
++
++    // Disable PCM
++    HAL_PCM_DISABLE_PCM();
++}
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  Hal_Pcm_Is_Transmit_Buffer_Empty
++ * PURPOSE:
++ *
++ ******************************************************************************/
++u_int32 Hal_Pcm_Is_Transmit_Buffer_Empty(void)
++{
++    /*
++     * Return value :
++     *    1 : PCM Tx Transmit Buffer Empty
++     *    0 : PCM Tx Transmit Buffer Not Empty
++     */    
++    return ((PCM_INTERRUPT_STATUS_REG & PCM_TXBUF_EMPTY_FG) ? 1 : 0);
++}
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  Hal_Pcm_Is_Receive_Buffer_Full
++ * PURPOSE:
++ *
++ ******************************************************************************/
++u_int32 Hal_Pcm_Is_Receive_Buffer_Full(void)
++{
++    /*
++     * Return value :
++     *    1 : PCM Rx Receive Buffer Full
++     *    0 : PCM Rx Receive Buffer Not Full
++     */    
++    return ((PCM_INTERRUPT_STATUS_REG & PCM_RXBUF_FULL_FG) ? 1 : 0);
++}
++
++/******************************************************************************
++ *
++ * FUNCTION:  Pcm_Configure_DMA_Hardware_Handshake_For_Legerity
++ * PURPOSE:
++ *
++ ******************************************************************************/
++void Pcm_Configure_DMA_Hardware_Handshake_For_Legerity(void)
++{
++
++	DEBUG_PRINT(" %s : ==>\n" ,__FUNCTION__);
++#if 1
++    /*
++     * Configure DMA's channel setting for PCM Transmit Data[31:0] Register
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++
++    pcm_tx_data0_dma_legerity.channel_id = DMAC_CH_ID(pcm_tx_data0_dma_channel_num);//0    
++    pcm_tx_data0_dma_legerity.target_select = DMAC_HW_HAND_SHAKE_PCM_TX0_ID;//0
++
++    pcm_tx_data0_dma_legerity.src_addr = (u_int32)pcm_tx0_buffer_le88221_p;//SCR        
++    pcm_tx_data0_dma_legerity.dst_addr = (SYSPA_PCM_BASE_ADDR + 0x98);//DST
++
++    pcm_tx_data0_dma_legerity.src_master = DMAC_CH_SRC_SEL_M1;//1
++    pcm_tx_data0_dma_legerity.dst_master = DMAC_CH_DST_SEL_M0;//0
++
++    pcm_tx_data0_dma_legerity.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;//0
++    pcm_tx_data0_dma_legerity.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;//2
++
++    pcm_tx_data0_dma_legerity.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    pcm_tx_data0_dma_legerity.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    // Note here the total number of bytes is specified!!
++    pcm_tx_data0_dma_legerity.transfer_bytes = BUFFER_SIZE * 4;
++
++    pcm_tx_data0_dma_legerity.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;//0   
++
++    // Note this DMA's channel will be enabled when the following function is invoked!!
++    Hal_Dmac_Configure_DMA_Handshake(&pcm_tx_data0_dma_legerity);
++
++
++    /*
++     * Configure DMA's channel setting for PCM Receive Data[31:0] Register
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    pcm_rx_data0_dma_legerity.channel_id = DMAC_CH_ID(pcm_rx_data0_dma_channel_num);//2    
++    pcm_rx_data0_dma_legerity.target_select = DMAC_HW_HAND_SHAKE_PCM_RX0_ID;//1
++
++    pcm_rx_data0_dma_legerity.src_addr = (SYSPA_PCM_BASE_ADDR + 0xA0);//SCR
++    pcm_rx_data0_dma_legerity.dst_addr = (u_int32)pcm_rx0_buffer_le88221_p;//DST        
++
++    pcm_rx_data0_dma_legerity.src_master = DMAC_CH_SRC_SEL_M0;//0
++    pcm_rx_data0_dma_legerity.dst_master = DMAC_CH_DST_SEL_M1;//1
++
++    pcm_rx_data0_dma_legerity.srcad_ctl = DMAC_CH_SRCAD_CTL_FIX;//2
++    pcm_rx_data0_dma_legerity.dstad_ctl = DMAC_CH_DSTAD_CTL_INC;//0
++
++    pcm_rx_data0_dma_legerity.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    pcm_rx_data0_dma_legerity.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    // Note here the total number of bytes is specified!!
++    pcm_rx_data0_dma_legerity.transfer_bytes = BUFFER_SIZE * 4;
++
++    pcm_rx_data0_dma_legerity.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;
++
++    // Note this DMA's channel will be enabled when the following function is invoked!!
++    Hal_Dmac_Configure_DMA_Handshake(&pcm_rx_data0_dma_legerity);
++#endif
++
++
++#if 0
++    /*
++     * Configure DMA's channel setting for PCM Transmit Data[31:0] Register
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */    
++    pcm_tx_data1_dma_legerity.channel_id = DMAC_CH_ID(pcm_tx_data1_dma_channel_num);//1
++    pcm_tx_data1_dma_legerity.target_select = DMAC_HW_HAND_SHAKE_PCM_TX1_ID;
++
++    pcm_tx_data1_dma_legerity.src_addr = (u_int32)pcm_tx1_buffer_le88221_p;
++    pcm_tx_data1_dma_legerity.dst_addr = (SYSPA_PCM_BASE_ADDR + 0x9C);    
++
++    pcm_tx_data1_dma_legerity.src_master = DMAC_CH_SRC_SEL_M1;
++    pcm_tx_data1_dma_legerity.dst_master = DMAC_CH_DST_SEL_M0;
++
++    pcm_tx_data1_dma_legerity.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;
++    pcm_tx_data1_dma_legerity.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;
++
++    pcm_tx_data1_dma_legerity.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    pcm_tx_data1_dma_legerity.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    // Note here the total number of bytes is specified!!
++    pcm_tx_data1_dma_legerity.transfer_bytes = BUFFER_SIZE * 4;
++
++    pcm_tx_data1_dma_legerity.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;
++
++    Hal_Dmac_Configure_DMA_Handshake(&pcm_tx_data1_dma_legerity);
++
++
++
++    /*
++     * Configure DMA's channel setting for PCM Receive Data[31:0] Register
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */    
++    pcm_rx_data1_dma_legerity.channel_id = DMAC_CH_ID(pcm_rx_data1_dma_channel_num);//3
++    pcm_rx_data1_dma_legerity.target_select = DMAC_HW_HAND_SHAKE_PCM_RX1_ID;
++    pcm_rx_data1_dma_legerity.src_addr = (SYSPA_PCM_BASE_ADDR + 0xA4);    
++    pcm_rx_data1_dma_legerity.dst_addr = (u_int32)pcm_rx1_buffer_le88221_p;    
++
++    pcm_rx_data1_dma_legerity.src_master = DMAC_CH_SRC_SEL_M0;
++    pcm_rx_data1_dma_legerity.dst_master = DMAC_CH_DST_SEL_M1;
++
++    pcm_rx_data1_dma_legerity.srcad_ctl = DMAC_CH_SRCAD_CTL_FIX;
++    pcm_rx_data1_dma_legerity.dstad_ctl = DMAC_CH_DSTAD_CTL_INC;
++
++    pcm_rx_data1_dma_legerity.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    pcm_rx_data1_dma_legerity.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    // Note here the total number of bytes is specified!!
++    pcm_rx_data1_dma_legerity.transfer_bytes = BUFFER_SIZE * 4;
++
++    pcm_rx_data1_dma_legerity.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;
++
++    Hal_Dmac_Configure_DMA_Handshake(&pcm_rx_data1_dma_legerity);    
++#endif            
++  
++    return;
++}
++
++#if 0
++static irqreturn_t str8100_pcm_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++    u_int32 volatile    interrupt_status;    
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++#if 1
++    PCM_INTERRUPT_STATUS_REG&=0xc0;
++
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++#endif
++	DEBUG_PRINT("%s: this_irq=%d, PCM_INTERRUPT_STATUS_REG=0x%.8x\n",__FUNCTION__,this_irq,PCM_INTERRUPT_STATUS_REG);
++
++    // Get PCM interrupt status
++    HAL_PCM_READ_INTERRUPT_STATUS(interrupt_status);   
++    if (interrupt_status & PCM_RXBUF_FULL_FG){
++    	rxbuf_full++;
++		DEBUG_PRINT("%s: rx buf full\n",__FUNCTION__);
++    }
++
++    if (interrupt_status & PCM_TXBUF_EMPTY_FG){
++    	txbuf_empty++;
++        DEBUG_PRINT("%s: tx buf empty\n",__FUNCTION__);
++    }
++    if (interrupt_status & PCM_RXBUF_OVERRUN_FG){
++        // Clear PCM interrupt status
++        HAL_PCM_CLEAR_INTERRUPT_STATUS(PCM_RXBUF_OVERRUN_FG);
++    
++        rxbuf_overrun++;
++        DEBUG_PRINT("%s: rx buf overrun\n",__FUNCTION__);
++    }
++
++    if (interrupt_status & PCM_TXBUF_UNDERRUN_FG){
++        // Clear PCM interrupt status
++        HAL_PCM_CLEAR_INTERRUPT_STATUS(PCM_TXBUF_UNDERRUN_FG);
++
++        txbuf_underrun++;
++        DEBUG_PRINT("%s: tx buf underrun\n",__FUNCTION__);
++    }
++    PCM_INTERRUPT_STATUS_REG&=0xc0;
++
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++#endif
++
++#ifdef CONFIG_SND_STAR_I2S_WM8759
++#define I2S_CHANNEL_NUM 2
++extern DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8759_dma_handshake_tx[I2S_CHANNEL_NUM];
++struct snd_star_i2s_wm8759_pcm_priv {
++	struct snd_star_i2s_wm8759_priv *card_priv;
++	spinlock_t lock;
++	struct timer_list timer;
++	unsigned int buffer_size_in_bytes;
++        unsigned int period_size_in_bytes;
++	unsigned int pcm_bps;		/* bytes per second */
++	unsigned int pcm_jiffie;	/* bytes per one jiffie */
++
++	unsigned int pcm_irq_pos[I2S_CHANNEL_NUM];	/* IRQ position */
++	unsigned int pcm_buf_pos[I2S_CHANNEL_NUM];	/* position in buffer */
++
++	u32 period_count_in_buffer; 	//(buffer_size/period_size)
++	u32 desc_count;		//period_count_in_buffer*channels
++
++	u32 desc_size_in_bytes;	//desc_count*sizeof(DMAC_LLP_T);
++	DMAC_LLP_T* desc;	//vir addr of desc buffer allocated
++	DMAC_LLP_T* desc_p;	//phy addr of desc buffer allocated
++
++	struct snd_pcm_substream *substream;
++};
++#endif
++
++static DECLARE_WAIT_QUEUE_HEAD(wg);
++static int swap_flag=0;
++static int call_swap_buffer(void)
++{
++	//current->pid, current->comm);
++	//printk(KERN_INFO "swap_flag=%d ...\n",swap_flag);
++
++	//wake up swap buffer
++	swap_flag=1;
++	wake_up_interruptible(&wg);
++	return 0;
++
++}
++
++
++static int swap_buffer_thread(void *data) 
++{
++	int i;
++	u_int32    *swap_buffer,*swap_buffer_p;
++	for(;;){
++		//printk(KERN_INFO "swap buffer start \n");
++		if(pcm_rx0_buffer_le88221==buffer0){
++			//printk("rx change to buffer1 \n");
++			swap_buffer=buffer2;
++			swap_buffer_p=buffer_p2;
++		}else if(pcm_rx0_buffer_le88221==buffer1){
++			//printk("rx change to buffer2 \n");
++			swap_buffer=buffer0;
++			swap_buffer_p=buffer_p0;
++
++		}else{
++			//printk("rx change to buffer0 \n");
++			swap_buffer=buffer1;
++			swap_buffer_p=buffer_p1;
++		}
++		for(i=0;i<BUFFER_SIZE;i++)
++			swap_buffer[i] = \
++			((swap_buffer[i] >> 8) & 0x000000FF) | \
++			((swap_buffer[i] << 8) & 0x0000FF00);
++
++		//printk("swap buffer end \n");
++		if(signal_pending(current))	
++			break;
++		wait_event_interruptible(wg, swap_flag !=0);
++		swap_flag=0;
++	}	
++	
++	return 1;
++}
++
++//static irqreturn_t str8100_dma_tc_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t str8100_dma_tc_irq_handler(int this_irq, void *dev_id)
++{
++    u_int32 volatile    dma_tc_status;
++	u32 i;
++
++	DEBUG_PRINT("%s: this_irq=%d,tc_status=0x%.8x\n",__FUNCTION__,this_irq,((DMAC_INT_TC_STATUS_REG) & 0xFF) );
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	HAL_DMAC_READ_TERMINAL_COUNT_INTERRUPT_STATUS(dma_tc_status);
++    HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_GDMAC_TC_BIT_INDEX);
++    HAL_DMAC_READ_TERMINAL_COUNT_INTERRUPT_STATUS(dma_tc_status);
++
++#ifdef CONFIG_SND_STAR_I2S_WM8759
++	if (dma_tc_status & DMAC_CH_ID(0) || dma_tc_status & DMAC_CH_ID(1))		// WM8759
++	{
++		for(i=0;i<I2S_CHANNEL_NUM;i++)
++		{
++			struct snd_pcm_substream *substream=(struct snd_pcm_substream *)i2s_wm8759_dma_handshake_tx[i].private_data;
++			struct snd_pcm_runtime *runtime = substream->runtime;
++			struct snd_star_i2s_wm8759_pcm_priv *dpcm = (struct snd_star_i2s_wm8759_pcm_priv *)runtime->private_data;
++			HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8759_dma_handshake_tx[i].channel_num));
++			dma_tc_status &= ~(DMAC_CH_ID(i2s_wm8759_dma_handshake_tx[i].channel_num));
++
++			//currently assume period size (in frames) is the DMA totsize
++			dpcm->pcm_irq_pos[i] += dpcm->period_size_in_bytes/runtime->channels;
++			dpcm->pcm_buf_pos[i] += dpcm->period_size_in_bytes/runtime->channels;
++			dpcm->pcm_buf_pos[i] %= dpcm->buffer_size_in_bytes/runtime->channels;
++
++			if (dpcm->pcm_irq_pos[i] >= (dpcm->period_size_in_bytes/runtime->channels)) {
++				dpcm->pcm_irq_pos[i] %= (dpcm->period_size_in_bytes/runtime->channels);
++				snd_pcm_period_elapsed(dpcm->substream);
++			}
++		}
++	}
++#endif
++
++    //DMA Rx reg 0
++    if (dma_tc_status & DMAC_CH_ID(pcm_rx_data0_dma_channel_num))
++    {
++        HAL_DMAC_DISABLE_CHANNEL(pcm_rx_data0_dma_channel_num);
++        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(pcm_rx_data0_dma_channel_num));
++        dma_tc_status &= ~(DMAC_CH_ID(pcm_rx_data0_dma_channel_num));
++
++        //make pcm ch0 to ch1, and vice versa
++		if(pcm_rx0_buffer_le88221==buffer0){
++			//printk("rx change to buffer1 \n");
++			pcm_rx0_buffer_le88221=buffer1;
++			pcm_rx0_buffer_le88221_p=buffer_p1;
++			
++		}
++        else if(pcm_rx0_buffer_le88221==buffer1){
++			//printk("rx change to buffer2 \n");
++			pcm_rx0_buffer_le88221=buffer2;
++			pcm_rx0_buffer_le88221_p=buffer_p2;
++
++		}else{
++			//printk("rx change to buffer0 \n");
++			pcm_rx0_buffer_le88221=buffer0;
++			pcm_rx0_buffer_le88221_p=buffer_p0;
++		}
++        
++        // Re-initialize DMA's channel for Rx
++        HAL_DMAC_WRITE_CHANNEL2_DESTINATION_ADDRESS((u_int32)pcm_rx0_buffer_le88221_p);
++        HAL_DMAC_WRITE_CHANNEL2_SOURCE_ADDRESS(SYSPA_PCM_BASE_ADDR + 0xA0);
++        HAL_DMAC_WRITE_CHANNEL2_TRANSFER_SIZE(BUFFER_SIZE);
++        HAL_DMAC_ENABLE_CHANNEL2();
++		call_swap_buffer();                        
++    }       
++
++    //DMA Tx reg 0
++    if (dma_tc_status & DMAC_CH_ID(pcm_tx_data0_dma_channel_num))
++    {
++        HAL_DMAC_DISABLE_CHANNEL(pcm_tx_data0_dma_channel_num);
++        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(pcm_tx_data0_dma_channel_num));
++        dma_tc_status &= ~(DMAC_CH_ID(pcm_tx_data0_dma_channel_num));
++
++		//swap buffer
++        if(pcm_tx0_buffer_le88221==buffer2) {
++			//printk("tx change to buffer0 \n");
++			pcm_tx0_buffer_le88221=buffer0;
++			pcm_tx0_buffer_le88221_p=buffer_p0;
++		}
++		else if(pcm_tx0_buffer_le88221==buffer1){
++			//printk("tx change to buffer2 \n");
++			pcm_tx0_buffer_le88221=buffer2;
++			pcm_tx0_buffer_le88221_p=buffer_p2;
++		}
++		else{
++			//printk("tx change to buffer1 \n");
++			pcm_tx0_buffer_le88221=buffer1;
++			pcm_tx0_buffer_le88221_p=buffer_p1;
++			}
++  
++        // Re-initialize DMA's channel for Tx
++        HAL_DMAC_WRITE_CHANNEL0_SOURCE_ADDRESS((u_int32)pcm_tx0_buffer_le88221_p);
++        HAL_DMAC_WRITE_CHANNEL0_DESTINATION_ADDRESS(SYSPA_PCM_BASE_ADDR + 0x98);
++        HAL_DMAC_WRITE_CHANNEL0_TRANSFER_SIZE(BUFFER_SIZE);
++        HAL_DMAC_ENABLE_CHANNEL0();
++    }       
++
++    /*
++     * If there is any bit set, it means something wrong!!
++     */
++    if (dma_tc_status)
++    {
++        // Something wrong because spurious interrupt happens!!
++        printk("Something wrong because spurious interrupt happens(%.8x)!!\n",dma_tc_status);
++    }
++
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++void pcm_init(void){
++	u32 flags;
++	//u32 tmp;
++	local_irq_save(flags);
++    /*
++     * Check CLK_OUT_SEL_Pin for 8.192 MHz
++     */
++	DEBUG_PRINT("%s:\n",__FUNCTION__);
++//    HAL_MISC_DISABLE_SPI_SERIAL_FLASH_BANK_ACCESS();
++    HAL_PWRMGT_CONFIGURE_CLOCK_OUT_PIN(10, 0);
++
++    /*
++     * For IDL Case:
++     *     UDCLK    : 4.096 MHz
++     *     PCMCLK   : 2.048 MHz = 4.096/(1 + 1)
++     *     FSYNCCLK : 8 KHz = 2048000/(255 + 1)
++     */
++    pcm_object.config_0 = ((/*clock_rate_ctrl*/1 & 0x7) << 0) |    /* Configure master clock rate */
++                          (0 << 12) |                   /* Disable loopback mode */
++                          (1 << 13) |                   /* Enable master mode */
++                          (0 << 14) |                   /* Select IDL mode */
++                          /*(1 << 24) | */                  /* Enable PCM data swap */
++                          (0 << 24) |                   /* Disable PCM data swap */
++                          (0 << 31);                    /* Disable PCM */
++
++    /*
++     * Note FSYNC_WIDE will be ignored when the PCM is configured as Slave or as Master
++     * with GCI mode
++     */    
++    pcm_object.config_1 = ((0 & 0x1) << 15);    /* Select FSYNC mode , 0 : short FSYNC, 1 : long FSYNC */
++
++
++    /*
++     * Configure the settings of PCM's channel
++     */
++    pcm_object.channel_0_config = ((CH0_TX_Le88221_DELAY & 0x7F) << 0) |
++                                  ((CH0_RX_Le88221_DELAY & 0x7F) << 8) |
++                                  ((PCM_DATA_BIT_8 & 0x1) << 22) |
++                                  (1 << 23);    /* Enable this channel */
++                                  
++    pcm_object.channel_1_config = ((CH1_TX_Le88221_DELAY & 0x7F) << 0) |
++                                  ((CH1_RX_Le88221_DELAY & 0x7F) << 8) |
++                                  ((PCM_DATA_BIT_8 & 0x1) << 22) |
++                                  (1 << 23);    /* Enable this channel */
++
++    pcm_object.channel_2_config = ((CH2_TX_Le88221_DELAY & 0x7F) << 0) |
++                                  ((CH2_RX_Le88221_DELAY & 0x7F) << 8) |
++                                  ((0 & 0x1) << 22) |
++                                  (0 << 23);    /* Disable this channel */
++
++    pcm_object.channel_3_config = ((CH3_TX_Le88221_DELAY & 0x7F) << 0) |
++                                  ((CH3_RX_Le88221_DELAY & 0x7F) << 8) |
++                                  ((0 & 0x1) << 22) |
++                                  (0 << 23);    /* Disable this channel */
++
++
++    // Enable PCM's interrupt sources
++//    pcm_object.interrupt_config = 0;
++    pcm_object.interrupt_config = PCM_RXBUF_OVERRUN_FG | PCM_TXBUF_UNDERRUN_FG;
++//    pcm_object.interrupt_config |=PCM_RXBUF_FULL_FG|PCM_TXBUF_EMPTY_FG;
++
++
++   
++    // Initialize PCM's setting
++    Hal_Pcm_Initialize(&pcm_object);
++    
++    
++    // Disable PCM interrupt since GDMA hardware handshake interrupt will be used.
++    //HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_PCM_BIT_INDEX);
++
++    // Initialize GDMA hardware handshake for PCM
++    Pcm_Configure_DMA_Hardware_Handshake_For_Legerity();
++
++
++    /*
++     * PCM will start to transmit and receive data once PCM is enabled. To avoid
++     * PCM Transmit Buffer underrun, we have to put one transmit data into PCM
++     * Transmit Buffer before PCM is enabled!!
++     * Note PCM channel 0 is used.
++     */
++/*
++	PCM_TX_DATA_31_0_REG=0;
++	PCM_TX_DATA_63_32_REG=0;
++
++	tmp=PCM_RX_DATA_31_0_REG;
++	tmp=PCM_RX_DATA_63_32_REG;
++*/
++    HAL_PCM_CLEAR_INTERRUPT_STATUS((PCM_RXBUF_OVERRUN_FG | PCM_TXBUF_UNDERRUN_FG));//(0x4 | 0x8)=0xC
++
++/*{
++	u32 dma_ch;
++	for (dma_ch = 0; dma_ch < DMAC_MAX_CHANNEL_NUM; dma_ch++)
++	{
++			HAL_DMAC_CLEAR_ERROR_ABORT_INTERRUPT_STATUS(DMAC_CH_ID(dma_ch));
++        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(dma_ch));
++	}	
++}
++*/
++    HAL_DMAC_ENABLE();    
++    HAL_PCM_ENABLE_PCM();
++
++    /*
++     * Configure Legerity's Le88221 MPI Interface
++     */
++    Pcm_Initial_Legerity_Le88221();
++	local_irq_restore(flags);
++
++    
++	DEBUG_PRINT("%s: end =>\n",__FUNCTION__);
++
++}
++
++//=================================================================================
++static int proc_read_pcm(char *buf, char **start, off_t offset,
++                   int count, int *eof, void *data)
++{
++	int len=0;
++	DEBUG_PRINT("%s:\n",__FUNCTION__);
++	len += sprintf(buf,	"test\n"
++				"test\n"); 
++	*eof = 1;
++	return len;
++}
++
++static int proc_write_pcm(struct file *file, const char *buffer, unsigned long count, void *data){
++	int len=0;
++	DEBUG_PRINT("%s: count=%ld\n",__FUNCTION__,count);
++	pcm_init();
++
++	return count;
++	//is buffer free?
++	if(txpos!=txlen){
++		printk("%s: buffer not free\n",__FUNCTION__);
++		return -EBUSY;
++	}
++
++	//copy the raw data to local buffer	
++	if(count>BUFFER_SIZE) len=BUFFER_SIZE;
++	else len=count;
++	
++	if(copy_from_user(txbuffer,buffer,len)){
++		return -EFAULT;	
++	}
++	txlen=len;
++	txpos=0;
++
++	//Initialization	
++
++	// Enable CPU interrupt
++	local_irq_enable();
++	
++	/*
++	 * Note DMA must be enabled first before PCM is enabled
++	 */
++	HAL_DMAC_ENABLE();
++
++
++	while (1){
++		local_irq_disable();
++		if (txpos>txlen||txlen==0){
++			// Disable PCM
++			
++			break;
++		}
++		local_irq_enable();
++	}
++	DEBUG_PRINT("%s: exit. \n",__FUNCTION__);
++
++	local_irq_enable();
++
++	return len;
++
++//debug:
++	
++//	return count;
++}
++
++static void __exit pcm_exit_module(void){
++	printk("%s:\n",__FUNCTION__);
++	remove_proc_entry("str8100/pcm", NULL);
++	free_irq(INTC_PCM_BIT_INDEX, NULL);
++	free_irq(INTC_GDMAC_TC_BIT_INDEX, NULL);
++	free_irq(INTC_GDMAC_ERROR_BIT_INDEX, NULL);
++/*	if(txbuffer) {
++		pci_free_consistent(NULL, BUFFER_SIZE*4, txbuffer, txbuffer_p);
++		txbuffer=txbuffer_p=NULL;
++	}
++*/
++#if 1
++	if(buffer0) {
++		pci_free_consistent(NULL, BUFFER_SIZE*4, buffer0, *buffer_p0);
++		buffer0=buffer_p0=NULL;
++	}
++
++	if(buffer1) {
++		pci_free_consistent(NULL, BUFFER_SIZE*4, buffer1, *buffer_p1);
++		buffer1=buffer_p1=NULL;
++	}
++	if(buffer2) {
++		pci_free_consistent(NULL, BUFFER_SIZE*4, buffer2, *buffer_p2);
++		buffer2=buffer_p2=NULL;
++	}
++
++	if(buffer3) {
++		pci_free_consistent(NULL, BUFFER_SIZE*4, buffer3, *buffer_p3);
++		buffer3=buffer_p3=NULL;
++	}
++#else
++	printk("%s:buffers not freed yet!!!\n",__FUNCTION__);
++#endif	
++}
++
++extern void str8100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++static int __init pcm_init_module(void)
++{
++	
++	u32 ret;
++	
++	printk("%s:\n",__FUNCTION__);
++
++	star_pcm_proc_entry = create_proc_entry("str8100/pcm", S_IFREG | S_IRUGO, NULL);
++	if(!star_pcm_proc_entry){
++		return -EBUSY;
++	}
++	star_pcm_proc_entry->read_proc=proc_read_pcm;
++	star_pcm_proc_entry->write_proc=proc_write_pcm;
++	
++/*
++	txbuffer = pci_alloc_consistent(NULL, BUFFER_SIZE, &txbuffer_p);
++	if(!txbuffer){
++		printk("%s: alloc txbuffer failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++*/
++	buffer0 = pci_alloc_consistent(NULL, BUFFER_SIZE*4, &buffer_p0);
++	if(!buffer0){
++		printk("%s: alloc buffer0 failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++	buffer1 = pci_alloc_consistent(NULL, BUFFER_SIZE*4, &buffer_p1);
++	if(!buffer1){
++		printk("%s: alloc buffer1 failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++	buffer2 = pci_alloc_consistent(NULL, BUFFER_SIZE*4, &buffer_p2);
++	if(!buffer2){
++		printk("%s: alloc buffer2 failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++	buffer3 = pci_alloc_consistent(NULL, BUFFER_SIZE*4, &buffer_p3);
++	if(!buffer3){
++		printk("%s: alloc buffer3 failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++	DEBUG_PRINT("%s: buffers allocated... \n",__FUNCTION__);
++
++	pcm_rx0_buffer_le88221=buffer0;
++	pcm_tx0_buffer_le88221=buffer1;
++	//pcm_rx1_buffer_le88221=buffer2;
++	//pcm_tx1_buffer_le88221=buffer3;
++	
++	pcm_rx0_buffer_le88221_p=buffer_p0;
++	pcm_tx0_buffer_le88221_p=buffer_p1;
++	//pcm_rx1_buffer_le88221_p=buffer_p2;
++	//pcm_tx1_buffer_le88221_p=buffer_p3;
++/*
++	str8100_set_interrupt_trigger (INTC_PCM_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_LOW);
++	if((ret=request_irq(INTC_PCM_BIT_INDEX, str8100_pcm_irq_handler, 0, "pcm", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_PCM_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++*/
++	str8100_set_interrupt_trigger (INTC_GDMAC_TC_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_TC_BIT_INDEX, str8100_dma_tc_irq_handler, 0, "dma tc", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_TC_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++	str8100_set_interrupt_trigger (INTC_GDMAC_ERROR_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_ERROR_BIT_INDEX, str8100_dma_err_irq_handler, 0, "dma error", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_ERROR_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++	kernel_thread(swap_buffer_thread, NULL, CLONE_KERNEL);
++
++	//pcm_init();
++
++	return 0;
++exit1:
++	//pcm_exit_module();
++	return -EBUSY;
++}
++
++module_init(pcm_init_module);
++module_exit(pcm_exit_module);
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_dma.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_dma.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_dma.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_dma.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,878 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/pci.h>
++#include <asm/io.h>
++#include <asm/delay.h>
++#include <mach/star_intc.h>
++#include <mach/star_dmac.h>
++
++//#define DMA_DEBUG
++//#define STR8100_DMA_TEST
++
++#define DMA_CHANNEL_MAX_ID		6 // channel 0 ~ 6
++
++#define DMA_XFER_MAX_Q_LEN		32
++#define DMA_BUSY_MAX_Q_LEN		7
++
++#define ADDR_16BIT_ALIGN_MASK		0x1
++#define ADDR_32BIT_ALIGN_MASK		0x3
++
++#define DMA_LEN_SHIFT_8BIT_WIDTH	0
++#define DMA_LEN_SHIFT_16BIT_WIDTH	1
++#define DMA_LEN_SHIFT_32BIT_WIDTH	2
++#define DMA_MAX_LEN_8BIT_WIDTH		0xfff
++#define DMA_MAX_LEN_16BIT_WIDTH		(0xfff << 1)
++#define DMA_MAX_LEN_32BIT_WIDTH		(0xfff << 2)
++
++#define DMA_COPY_BUSY_WAIT_CHANNEL	7
++#define DMA_COPY_BUSY_WAIT_LOOP		1000
++
++static u32 dma_burst_size = DMAC_CH_SRC_BURST_SIZE_32;
++
++#define DEFAULT_CH_PRIORITY		DMAC_CH_PRIORITY_3
++#define DEFAULT_CH_BURST_SIZE		DMAC_CH_SRC_BURST_SIZE_128
++#define DEFAULT_CH_SRC_WIDTH		DMAC_CH_SRC_WIDTH_8BIT
++#define DEFAULT_CH_DST_WIDTH		DMAC_CH_SRC_WIDTH_8BIT
++#define DEFAULT_CH_MODE			DMAC_CH_MODE_NORMAL
++#define DEFAULT_CH_SRC_ADDR_CTL		DMAC_CH_SRC_ADDR_CTL_INC
++#define DEFAULT_CH_DST_ADDR_CTL		DMAC_CH_DST_ADDR_CTL_INC
++#define DEFAULT_CH_DST_SEL		DMAC_DST_SEL_MASTER0
++#define DEFAULT_CH_SRC_SEL		DMAC_SRC_SEL_MASTER0
++
++#define DEFAULT_DMA_CH_CTL \
++	((0xf				<< DMAC_CH_HHST_SEL_BIT_INDEX) | \
++	 (DEFAULT_CH_PRIORITY		<< DMAC_CH_PRIORITY_BIT_INDEX) | \
++	 (DEFAULT_CH_BURST_SIZE		<< DMAC_CH_SRC_BURST_SIZE_BIT_INDEX) | \
++	 (DEFAULT_CH_SRC_WIDTH		<< DMAC_CH_SRC_WIDTH_BIT_INDEX) | \
++	 (DEFAULT_CH_DST_WIDTH		<< DMAC_CH_DST_WIDTH_BIT_INDEX) | \
++	 (DEFAULT_CH_MODE		<< DMAC_CH_MODE_BIT_INDEX) | \
++	 (DEFAULT_CH_SRC_ADDR_CTL	<< DMAC_CH_SRC_ADDR_CTL_BIT_INDEX) | \
++	 (DEFAULT_CH_DST_ADDR_CTL	<< DMAC_CH_DST_ADDR_CTL_BIT_INDEX) | \
++	 (DEFAULT_CH_DST_SEL		<< DMAC_CH_DST_SEL_BIT_INDEX) | \
++	 (DEFAULT_CH_SRC_SEL		<< DMAC_CH_SRC_SEL_BIT_INDEX))
++
++#define DMA_CH_CTL_8BIT_WIDTH \
++	((0xf				<< DMAC_CH_HHST_SEL_BIT_INDEX) | \
++	 (DMAC_CH_PRIORITY_3		<< DMAC_CH_PRIORITY_BIT_INDEX) | \
++	 (dma_burst_size		<< DMAC_CH_SRC_BURST_SIZE_BIT_INDEX) | \
++	 (DMAC_CH_SRC_WIDTH_8BIT	<< DMAC_CH_SRC_WIDTH_BIT_INDEX) | \
++	 (DMAC_CH_DST_WIDTH_8BIT	<< DMAC_CH_DST_WIDTH_BIT_INDEX) | \
++	 (DMAC_CH_MODE_NORMAL		<< DMAC_CH_MODE_BIT_INDEX) | \
++	 (DMAC_CH_SRC_ADDR_CTL_INC	<< DMAC_CH_SRC_ADDR_CTL_BIT_INDEX) | \
++	 (DMAC_CH_DST_ADDR_CTL_INC	<< DMAC_CH_DST_ADDR_CTL_BIT_INDEX) | \
++	 (DMAC_DST_SEL_MASTER0		<< DMAC_CH_DST_SEL_BIT_INDEX) | \
++	 (DMAC_SRC_SEL_MASTER1		<< DMAC_CH_SRC_SEL_BIT_INDEX))
++
++#define DMA_CH_CTL_16BIT_WIDTH \
++	((0xf				<< DMAC_CH_HHST_SEL_BIT_INDEX) | \
++	 (DMAC_CH_PRIORITY_3		<< DMAC_CH_PRIORITY_BIT_INDEX) | \
++	 (dma_burst_size		<< DMAC_CH_SRC_BURST_SIZE_BIT_INDEX) | \
++	 (DMAC_CH_SRC_WIDTH_16BIT	<< DMAC_CH_SRC_WIDTH_BIT_INDEX) | \
++	 (DMAC_CH_DST_WIDTH_16BIT	<< DMAC_CH_DST_WIDTH_BIT_INDEX) | \
++	 (DMAC_CH_MODE_NORMAL		<< DMAC_CH_MODE_BIT_INDEX) | \
++	 (DMAC_CH_SRC_ADDR_CTL_INC	<< DMAC_CH_SRC_ADDR_CTL_BIT_INDEX) | \
++	 (DMAC_CH_DST_ADDR_CTL_INC	<< DMAC_CH_DST_ADDR_CTL_BIT_INDEX) | \
++	 (DMAC_DST_SEL_MASTER0		<< DMAC_CH_DST_SEL_BIT_INDEX) | \
++	 (DMAC_SRC_SEL_MASTER1		<< DMAC_CH_SRC_SEL_BIT_INDEX))
++
++
++#define DMA_CH_CTL_32BIT_WIDTH \
++	((0xf				<< DMAC_CH_HHST_SEL_BIT_INDEX) | \
++	 (DMAC_CH_PRIORITY_3		<< DMAC_CH_PRIORITY_BIT_INDEX) | \
++	 (dma_burst_size		<< DMAC_CH_SRC_BURST_SIZE_BIT_INDEX) | \
++	 (DMAC_CH_SRC_WIDTH_32BIT	<< DMAC_CH_SRC_WIDTH_BIT_INDEX) | \
++	 (DMAC_CH_DST_WIDTH_32BIT	<< DMAC_CH_DST_WIDTH_BIT_INDEX) | \
++	 (DMAC_CH_MODE_NORMAL		<< DMAC_CH_MODE_BIT_INDEX) | \
++	 (DMAC_CH_SRC_ADDR_CTL_INC	<< DMAC_CH_SRC_ADDR_CTL_BIT_INDEX) | \
++	 (DMAC_CH_DST_ADDR_CTL_INC	<< DMAC_CH_DST_ADDR_CTL_BIT_INDEX) | \
++	 (DMAC_DST_SEL_MASTER0		<< DMAC_CH_DST_SEL_BIT_INDEX) | \
++	 (DMAC_SRC_SEL_MASTER1		<< DMAC_CH_SRC_SEL_BIT_INDEX))
++
++typedef struct
++{
++	struct list_head	lh;
++	dma_xfer_t		*xfer;
++	dma_llp_descr_t		*llp_descr;
++	u32			llp_descr_dma;
++	int			done_status;
++} dma_job_t;
++
++
++static u8 dma_dev;
++static spinlock_t dma_lock;
++static u8 dma_busy;
++static u8 dma_busy_q_len;
++static unsigned int dma_xfer_q_len;
++static unsigned int dma_done_q_len;
++static struct list_head dma_xfer_q;
++static struct list_head dma_done_q;
++static dma_job_t *dma_running_job[DMA_CHANNEL_MAX_ID + 1];
++
++static void *dma_mem_pool;
++static u32 dma_mem_pool_dma;
++
++static dma_job_t dma_job_pool[DMA_XFER_MAX_Q_LEN];
++static struct list_head dma_job_q;
++static spinlock_t dma_job_q_lock;
++
++static void dma_process_xfer_job(void *data);
++static void dma_process_done_job(void *data);
++
++// Eileen , for linux kernel 2.6.24 , 20080424
++//old : static DECLARE_WORK(dma_xfer_task, dma_process_xfer_job, (void *)&dma_xfer_q);
++//old : static DECLARE_WORK(dma_done_task, dma_process_done_job, (void *)&dma_done_q);
++static DECLARE_WORK(dma_xfer_task, dma_process_xfer_job);
++static DECLARE_WORK(dma_done_task, dma_process_done_job);
++
++static int dma_job_q_init(void)
++{
++	int i;
++
++	dma_mem_pool = (void *)pci_alloc_consistent(NULL,
++		(DMA_XFER_MAX_Q_LEN * MAX_DMA_VEC * sizeof(dma_llp_descr_t)),
++	       	&dma_mem_pool_dma);
++
++	if (dma_mem_pool == NULL) {
++		return -1;
++	}
++
++	INIT_LIST_HEAD(&dma_job_q);
++	for (i = 0; i < DMA_XFER_MAX_Q_LEN; i++) {
++		INIT_LIST_HEAD(&dma_job_pool[i].lh);
++		dma_job_pool[i].llp_descr = (dma_llp_descr_t *)(dma_mem_pool + (i * (MAX_DMA_VEC * sizeof(dma_llp_descr_t))));
++		dma_job_pool[i].llp_descr_dma = dma_mem_pool_dma + (i * (MAX_DMA_VEC * sizeof(dma_llp_descr_t)));
++		list_add_tail(&dma_job_pool[i].lh, &dma_job_q);
++	}
++
++	return 0;
++}
++
++static dma_job_t *dma_job_alloc(void)
++{
++	dma_job_t *job;
++	unsigned long flags;
++
++	spin_lock_irqsave(&dma_job_q_lock, flags);
++	if (list_empty(&dma_job_q)) {
++		job = NULL;
++	} else {
++		job = list_entry(dma_job_q.next, dma_job_t, lh);
++		list_del_init(&job->lh);
++	}
++	spin_unlock_irqrestore(&dma_job_q_lock, flags);
++
++	return job;
++}
++
++static void dma_job_free(dma_job_t *job)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&dma_job_q_lock, flags);
++	list_add(&job->lh, &dma_job_q);
++	spin_unlock_irqrestore(&dma_job_q_lock, flags);
++}
++
++#ifdef DMA_DEBUG
++void dma_dump_reg(void)
++{
++	printk("DMAC_BASE_ADDR+0x000: 0x%08x\n", DMAC_INT_STATUS_REG);
++	printk("DMAC_BASE_ADDR+0x004: 0x%08x\n", DMAC_INT_TC_STATUS_REG);
++	printk("DMAC_BASE_ADDR+0x008: 0x%08x\n", DMAC_INT_TC_STATUS_CLR_REG);
++	printk("DMAC_BASE_ADDR+0x00C: 0x%08x\n", DMAC_INT_ERR_STATUS_REG);
++	printk("DMAC_BASE_ADDR+0x010: 0x%08x\n", DMAC_INT_ERR_STATUS_CLR_REG);
++	printk("DMAC_BASE_ADDR+0x014: 0x%08x\n", DMAC_TC_STATUS_REG);
++	printk("DMAC_BASE_ADDR+0x018: 0x%08x\n", DMAC_ERR_STATUS_REG);
++	printk("DMAC_BASE_ADDR+0x01C: 0x%08x\n", DMAC_CH_ENABLE_STATUS_REG);
++	printk("DMAC_BASE_ADDR+0x020: 0x%08x\n", DMAC_CH_BUSY_STATUS_REG);
++	printk("DMAC_BASE_ADDR+0x024: 0x%08x\n", DMAC_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x028: 0x%08x\n", DMAC_SYNC_REG);
++	printk("DMAC_BASE_ADDR+0x100: 0x%08x\n", DMAC_CH0_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x104: 0x%08x\n", DMAC_CH0_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x108: 0x%08x\n", DMAC_CH0_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x10C: 0x%08x\n", DMAC_CH0_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x110: 0x%08x\n", DMAC_CH0_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x114: 0x%08x\n", DMAC_CH0_SIZE_REG);
++	printk("DMAC_BASE_ADDR+0x120: 0x%08x\n", DMAC_CH1_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x124: 0x%08x\n", DMAC_CH1_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x128: 0x%08x\n", DMAC_CH1_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x12C: 0x%08x\n", DMAC_CH1_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x130: 0x%08x\n", DMAC_CH1_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x134: 0x%08x\n", DMAC_CH1_SIZE_REG);
++	printk("DMAC_BASE_ADDR+0x140: 0x%08x\n", DMAC_CH2_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x144: 0x%08x\n", DMAC_CH2_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x148: 0x%08x\n", DMAC_CH2_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x14C: 0x%08x\n", DMAC_CH2_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x150: 0x%08x\n", DMAC_CH2_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x154: 0x%08x\n", DMAC_CH2_SIZE_REG);
++	printk("DMAC_BASE_ADDR+0x160: 0x%08x\n", DMAC_CH3_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x164: 0x%08x\n", DMAC_CH3_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x168: 0x%08x\n", DMAC_CH3_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x16C: 0x%08x\n", DMAC_CH3_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x170: 0x%08x\n", DMAC_CH3_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x174: 0x%08x\n", DMAC_CH3_SIZE_REG);
++	printk("DMAC_BASE_ADDR+0x180: 0x%08x\n", DMAC_CH4_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x184: 0x%08x\n", DMAC_CH4_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x188: 0x%08x\n", DMAC_CH4_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x18C: 0x%08x\n", DMAC_CH4_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x190: 0x%08x\n", DMAC_CH4_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x194: 0x%08x\n", DMAC_CH4_SIZE_REG);
++	printk("DMAC_BASE_ADDR+0x1A0: 0x%08x\n", DMAC_CH5_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x1A4: 0x%08x\n", DMAC_CH5_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x1A8: 0x%08x\n", DMAC_CH5_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x1AC: 0x%08x\n", DMAC_CH5_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x1B0: 0x%08x\n", DMAC_CH5_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x1B4: 0x%08x\n", DMAC_CH5_SIZE_REG);
++	printk("DMAC_BASE_ADDR+0x1C0: 0x%08x\n", DMAC_CH6_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x1C4: 0x%08x\n", DMAC_CH6_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x1C8: 0x%08x\n", DMAC_CH6_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x1CC: 0x%08x\n", DMAC_CH6_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x1D0: 0x%08x\n", DMAC_CH6_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x1D4: 0x%08x\n", DMAC_CH6_SIZE_REG);
++	printk("DMAC_BASE_ADDR+0x1E0: 0x%08x\n", DMAC_CH7_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x1E4: 0x%08x\n", DMAC_CH7_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x1E8: 0x%08x\n", DMAC_CH7_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x1EC: 0x%08x\n", DMAC_CH7_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x1F0: 0x%08x\n", DMAC_CH7_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x1F4: 0x%08x\n", DMAC_CH7_SIZE_REG);
++}
++#endif
++
++static inline void dma_copy_busy_wait(void *dst, const void *src, size_t len, unsigned long dma_len_shift)
++{
++	int err = 0;
++	int i;
++
++	len = (len >> dma_len_shift);
++
++	while ((DMAC_CH_BUSY_STATUS_REG & 0xFF) & (1 << DMA_COPY_BUSY_WAIT_CHANNEL)) {
++		udelay(1);
++	}
++
++	DMAC_CH_SRC_ADDR_REG(DMA_COPY_BUSY_WAIT_CHANNEL)	= (u32)virt_to_phys((void *)src);
++	DMAC_CH_DST_ADDR_REG(DMA_COPY_BUSY_WAIT_CHANNEL)	= (u32)virt_to_phys((void *)dst);
++	DMAC_CH_SIZE_REG(DMA_COPY_BUSY_WAIT_CHANNEL)		= (u32)len;
++
++#ifdef DMA_DEBUG
++	dma_dump_reg();
++#endif
++
++	// enable the channel
++	DMAC_CH_CSR_REG(DMA_COPY_BUSY_WAIT_CHANNEL) |= 0x1;
++
++	for (i = 0; i < DMA_COPY_BUSY_WAIT_LOOP; i++) {
++		if (DMAC_TC_STATUS_REG & (1 << DMA_COPY_BUSY_WAIT_CHANNEL)) {
++			break;
++		}
++		if (DMAC_ERR_STATUS_REG & (1 << DMA_COPY_BUSY_WAIT_CHANNEL)) {
++			err = 1;
++			break;
++		}
++		udelay(1);
++	}
++
++	// disable the channel
++	DMAC_CH_CSR_REG(DMA_COPY_BUSY_WAIT_CHANNEL) &= ~0x1;
++
++	if (err || (i == DMA_COPY_BUSY_WAIT_LOOP)) {
++		if (err) {
++			// clear the ERROR status
++			DMAC_INT_ERR_STATUS_CLR_REG |= (1 << DMA_COPY_BUSY_WAIT_CHANNEL);
++		}
++		memcpy(dst, src, (len << dma_len_shift));
++	} else {
++		// clear the TC status
++		DMAC_INT_TC_STATUS_CLR_REG |= (1 << DMA_COPY_BUSY_WAIT_CHANNEL);
++	}
++}
++
++void dma_memcpy_busy_wait(void *dst, const void *src, size_t len)
++{
++	void *pdst = dst;
++	const void *psrc = src;
++	unsigned long dma_len_shift;
++	unsigned long dma_max_len;
++	unsigned long flags;
++
++#ifdef DMA_DEBUG
++	printk("dst: 0x%08x\n", (u32)dst);
++	printk("src: 0x%08x\n", (u32)src);
++	printk("len: 0x%08x\n", (u32)len);
++	printk("pdst: 0x%08x\n", (u32)pdst);
++	printk("psrc: 0x%08x\n", (u32)psrc);
++#endif
++
++	local_irq_save(flags);
++	
++	// Eileen , for linux kernel 2.6.24 , 20080424
++	// old : consistent_sync((void *)src, len, PCI_DMA_TODEVICE);
++	// old : consistent_sync((void *)dst, len, PCI_DMA_FROMDEVICE);
++	dma_cache_maint((void *)src, len, PCI_DMA_TODEVICE);
++	dma_cache_maint((void *)dst, len, PCI_DMA_FROMDEVICE);
++
++	if ((((u32)psrc & ADDR_32BIT_ALIGN_MASK) == 0) &&
++		(((u32)pdst & ADDR_32BIT_ALIGN_MASK) == 0) &&
++		((len & 3) == 0)) {
++		dma_len_shift = DMA_LEN_SHIFT_32BIT_WIDTH;
++		dma_max_len = DMA_MAX_LEN_32BIT_WIDTH;
++		DMAC_CH_CSR_REG(DMA_COPY_BUSY_WAIT_CHANNEL) = DMA_CH_CTL_32BIT_WIDTH;
++	} else if ((((u32)psrc & ADDR_16BIT_ALIGN_MASK) == 0) &&
++		(((u32)pdst & ADDR_16BIT_ALIGN_MASK) == 0) &&
++		((len & 1) == 0)) {
++		dma_len_shift = DMA_LEN_SHIFT_16BIT_WIDTH;
++		dma_max_len = DMA_MAX_LEN_16BIT_WIDTH;
++		DMAC_CH_CSR_REG(DMA_COPY_BUSY_WAIT_CHANNEL) = DMA_CH_CTL_16BIT_WIDTH;
++	} else {
++		dma_len_shift = DMA_LEN_SHIFT_8BIT_WIDTH;
++		dma_max_len = DMA_MAX_LEN_8BIT_WIDTH;
++		DMAC_CH_CSR_REG(DMA_COPY_BUSY_WAIT_CHANNEL) = DMA_CH_CTL_8BIT_WIDTH;
++	}
++
++	while (len) {
++		if (len > dma_max_len) {
++			dma_copy_busy_wait(pdst, psrc, dma_max_len, dma_len_shift);
++			pdst += dma_max_len;
++			psrc += dma_max_len;
++			len -= dma_max_len;
++		} else {
++			dma_copy_busy_wait(pdst, psrc, len, dma_len_shift);
++			len = 0;
++		}
++	}
++
++	local_irq_restore(flags);
++}
++EXPORT_SYMBOL(dma_memcpy_busy_wait);
++
++void dma_copy(dma_xfer_t *dma_xfer)
++{
++	dma_job_t *dma_job;
++	u32 size_shift = 0;
++	unsigned long flags;
++	int i;
++
++	if (dma_xfer_q_len > DMA_XFER_MAX_Q_LEN) {
++		dma_xfer->dma_end_io(dma_xfer, DMAC_RESPONSE_ERR);
++		return;
++	}
++
++	dma_job = dma_job_alloc();
++	if (dma_job == NULL) {
++		dma_xfer->dma_end_io(dma_xfer, DMAC_RESPONSE_ERR);
++		return;
++	}
++
++	memset(dma_job->llp_descr, 0, (dma_xfer->nr_vec * sizeof(dma_llp_descr_t)));
++	for (i = 0; i < dma_xfer->nr_vec; i++) {
++		// Eileen , for linux kernel 2.6.24 , 20080424
++		//old : consistent_sync((void *)dma_xfer->vec[i].src_addr, dma_xfer->vec[i].size, PCI_DMA_TODEVICE);
++		//old : consistent_sync((void *)dma_xfer->vec[i].dst_addr, dma_xfer->vec[i].size, PCI_DMA_FROMDEVICE);
++		dma_cache_maint((void *)dma_xfer->vec[i].src_addr, dma_xfer->vec[i].size, PCI_DMA_TODEVICE);
++		dma_cache_maint((void *)dma_xfer->vec[i].dst_addr, dma_xfer->vec[i].size, PCI_DMA_FROMDEVICE);
++		dma_job->llp_descr[i].src_addr = (u32)virt_to_phys((void *)dma_xfer->vec[i].src_addr);
++		dma_job->llp_descr[i].dst_addr = (u32)virt_to_phys((void *)dma_xfer->vec[i].dst_addr);
++		dma_job->llp_descr[i].dst_sel = dma_xfer->vec[i].dst_sel;
++		dma_job->llp_descr[i].src_sel = dma_xfer->vec[i].src_sel;
++		dma_job->llp_descr[i].dst_addr_ctl = dma_xfer->vec[i].dst_sel;
++		dma_job->llp_descr[i].src_addr_ctl = dma_xfer->vec[i].src_sel;
++		dma_job->llp_descr[i].dst_width = dma_xfer->vec[i].dst_width;
++		dma_job->llp_descr[i].src_width = dma_xfer->vec[i].src_width;
++		if (dma_xfer->vec[i].src_width == DMAC_CH_DST_WIDTH_32BIT) {
++			size_shift = 2;
++		} else if (dma_xfer->vec[i].src_width == DMAC_CH_DST_WIDTH_16BIT) {
++			size_shift = 1;
++		} else {
++			size_shift = 0;
++		}
++		dma_job->llp_descr[i].tot_size = (dma_xfer->vec[i].size >> size_shift) & 0xFFF;
++		if (i == (dma_xfer->nr_vec - 1)) {
++			dma_job->llp_descr[i].llp = 0;
++			dma_job->llp_descr[i].tc_mask = 0;
++		} else {
++			dma_job->llp_descr[i].llp = (u32)(dma_job->llp_descr_dma + ((i + 1) * sizeof(dma_llp_descr_t)));
++			dma_job->llp_descr[i].tc_mask = 1;
++		}
++#ifdef DMA_DEBUG
++		printk("in src_addr:  0x%08x\n", dma_xfer->vec[i].src_addr);
++		printk("in dst_addr:  0x%08x\n", dma_xfer->vec[i].dst_addr);
++		printk("src_addr:     0x%08x\n", dma_job->llp_descr[i].src_addr);
++		printk("dst_addr:     0x%08x\n", dma_job->llp_descr[i].dst_addr);
++		printk("llp:          0x%08x\n", dma_job->llp_descr[i].llp);
++		printk("tot_size:     0x%08x\n", dma_job->llp_descr[i].tot_size);
++		printk("dst_sel:      0x%08x\n", dma_job->llp_descr[i].dst_sel);
++		printk("src_sel:      0x%08x\n", dma_job->llp_descr[i].src_sel);
++		printk("dst_addr_ctl: 0x%08x\n", dma_job->llp_descr[i].dst_addr_ctl);
++		printk("src_addr_ctl: 0x%08x\n", dma_job->llp_descr[i].src_addr_ctl);
++		printk("dst_width:    0x%08x\n", dma_job->llp_descr[i].dst_width);
++		printk("src_width:    0x%08x\n", dma_job->llp_descr[i].src_width);
++		printk("tc_mask:      0x%08x\n", dma_job->llp_descr[i].tc_mask);
++#endif
++	}
++
++	dma_job->xfer = dma_xfer;
++	dma_job->done_status = 0;
++
++	spin_lock_irqsave(&dma_lock, flags);
++	list_add_tail(&dma_job->lh, &dma_xfer_q);
++	dma_xfer_q_len++;
++	spin_unlock_irqrestore(&dma_lock, flags);
++
++	if (!dma_busy) {
++		schedule_work(&dma_xfer_task);
++	}
++}
++EXPORT_SYMBOL(dma_copy);
++
++static void dma_process_xfer_job(void *data)
++{
++	struct list_head *l, *t;
++	dma_job_t *dma_job;
++	unsigned long csr_reg;
++	int i;
++	unsigned long flags;
++
++	if (dma_busy) {
++		return;
++	}
++
++	spin_lock_irqsave(&dma_lock, flags);
++	list_for_each_safe(l, t, &dma_xfer_q) {
++		dma_job = list_entry(l, dma_job_t, lh);
++		for (i = 0; i <= 6; i++) {
++			if (dma_running_job[i] != NULL) {
++				continue;
++			}
++			printk("Insert dma xfer to channel(%d)\n", i);
++			list_del_init(&dma_job->lh);
++			dma_running_job[i] = dma_job;
++			dma_xfer_q_len--;
++			dma_busy_q_len++;
++			csr_reg = DMAC_CH_CSR_REG(i);
++			if (dma_job->llp_descr[0].tc_mask) {
++				csr_reg |= (1 << 31);
++			} else {
++				csr_reg &= ~(1 << 31);
++			}
++			csr_reg &= ~(DMAC_CH_SRC_WIDTH_MASK << DMAC_CH_SRC_WIDTH_BIT_INDEX);
++			csr_reg &= ~(DMAC_CH_DST_WIDTH_MASK << DMAC_CH_DST_WIDTH_BIT_INDEX);
++			csr_reg &= ~(DMAC_CH_SRC_ADDR_CTL_MASK << DMAC_CH_SRC_ADDR_CTL_BIT_INDEX);
++			csr_reg &= ~(DMAC_CH_DST_ADDR_CTL_MASK << DMAC_CH_DST_ADDR_CTL_BIT_INDEX);
++			csr_reg |=
++				((dma_job->llp_descr[0].src_width << DMAC_CH_SRC_WIDTH_BIT_INDEX) |
++				 (dma_job->llp_descr[0].dst_width << DMAC_CH_DST_WIDTH_BIT_INDEX) |
++				 (dma_job->llp_descr[0].src_addr_ctl << DMAC_CH_SRC_ADDR_CTL_BIT_INDEX) |
++				 (dma_job->llp_descr[0].dst_addr_ctl << DMAC_CH_DST_ADDR_CTL_BIT_INDEX) |
++				 (dma_job->llp_descr[0].src_sel << DMAC_CH_SRC_SEL_BIT_INDEX) |
++				 (dma_job->llp_descr[0].dst_sel << DMAC_CH_DST_SEL_BIT_INDEX));
++			DMAC_CH_CSR_REG(i) = csr_reg;
++
++#if 0
++			if (dma_job->llp_descr[0].tc_mask) {
++				DMAC_CH_CFG_REG(i) |= 0x1;
++			} else {
++				DMAC_CH_CFG_REG(i) &= ~0x1;
++			}
++#endif
++
++			DMAC_CH_SRC_ADDR_REG(i) = dma_job->llp_descr[0].src_addr;
++			DMAC_CH_DST_ADDR_REG(i) = dma_job->llp_descr[0].dst_addr;
++			DMAC_CH_LLP_REG(i) = dma_job->llp_descr[0].llp;
++			DMAC_CH_SIZE_REG(i) = dma_job->llp_descr[0].tot_size;
++			HAL_DMAC_ENABLE_CHANNEL(i);
++			break;
++#ifdef DMA_DEBUG
++			//dma_dump_reg();
++#endif
++		}
++		if (dma_busy_q_len == DMA_BUSY_MAX_Q_LEN) {
++			dma_busy = 1;
++			break;
++		}
++	}
++	spin_unlock_irqrestore(&dma_lock, flags);
++}
++
++static void dma_process_done_job(void *data)
++{
++	dma_job_t *dma_job;
++	struct list_head *l, *t;
++	unsigned long flags;
++
++	spin_lock_irqsave(&dma_lock, flags);
++	list_for_each_safe(l, t, &dma_done_q) {
++		dma_job = list_entry(l, dma_job_t, lh);
++		list_del_init(&dma_job->lh);
++		dma_done_q_len--;
++		spin_unlock_irqrestore(&dma_lock, flags);
++		dma_job->xfer->dma_end_io(dma_job->xfer, dma_job->done_status);
++		dma_job_free(dma_job);
++		spin_lock_irqsave(&dma_lock, flags);
++	}
++	spin_unlock_irqrestore(&dma_lock, flags);
++}
++// Eileen , for linux kernel 2.6.24 , 20080424
++//old : irqreturn_t dma_tc_isr(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t dma_tc_isr(int irq, void *dev_id)
++{
++	dma_job_t *dma_job;
++	u32 tc_status;
++	int i;
++
++	tc_status = DMAC_INT_TC_STATUS_REG;
++
++	for (i = 0; i <= 6; i++) {
++		if (tc_status & (1 << i)) {
++			HAL_DMAC_DISABLE_CHANNEL(i);
++			dma_job = dma_running_job[i];
++			if (dma_job) {
++				dma_running_job[i] = NULL;
++				dma_job->done_status = DMAC_RESPONSE_OK;
++				list_add_tail(&dma_job->lh, &dma_done_q);
++				dma_done_q_len++;
++				dma_busy_q_len--;
++				if (dma_busy) {
++					dma_busy = 0;
++				}
++				schedule_work(&dma_done_task);
++				if (dma_xfer_q_len) {
++					schedule_work(&dma_xfer_task);
++				}
++			}
++			DMAC_INT_TC_STATUS_CLR_REG |= (1 << i);
++			break;
++		}
++	}
++
++	return IRQ_HANDLED;
++}
++
++// Eileen ,for linux kernel 2.6.24 , 20080424
++//irqreturn_t dma_err_isr(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t dma_err_isr(int irq, void *dev_id)
++{
++	dma_job_t *dma_job;
++	u32 err_status;
++	int i;
++
++	err_status = DMAC_INT_ERR_STATUS_REG;
++
++	for (i = 0; i <= 6; i++) {
++		if (err_status & (1 << i)) {
++			HAL_DMAC_DISABLE_CHANNEL(i);
++			dma_job = dma_running_job[i];
++			if (dma_job) {
++				dma_running_job[i] = NULL;
++				dma_job->done_status = DMAC_RESPONSE_ERR;
++				list_add_tail(&dma_job->lh, &dma_done_q);
++				dma_done_q_len++;
++				dma_busy_q_len--;
++				if (dma_busy) {
++					dma_busy = 0;
++				}
++				schedule_work(&dma_done_task);
++				if (dma_xfer_q_len) {
++					schedule_work(&dma_xfer_task);
++				}
++			}
++			DMAC_INT_ERR_STATUS_CLR_REG |= (1 << i);
++			break;
++		}
++	}
++
++	return IRQ_HANDLED;
++}
++
++void dma_channel_init(void)
++{
++	int i;
++
++	// disable the channel
++	DMAC_CH_CSR_REG(DMA_COPY_BUSY_WAIT_CHANNEL) &= ~0x1;
++	DMAC_CH_CFG_REG(DMA_COPY_BUSY_WAIT_CHANNEL) = 0x7;
++
++	for (i = 0; i <= 6; i++) {
++		HAL_DMAC_DISABLE_CHANNEL(i);
++		DMAC_CH_CSR_REG(i) = DEFAULT_DMA_CH_CTL;
++		DMAC_CH_CFG_REG(i) &= ~0x3;
++	}
++
++	return;
++}
++
++static int dma_init(void)
++{
++	int retval;
++
++	HAL_PWRMGT_ENABLE_DMA_CLOCK();
++
++	// Master0 & Master1 in Little Endian Mode, DMA Controller Enable
++	DMAC_CSR_REG = 0x1;
++
++	if (dma_job_q_init() != 0) {
++		return -EFAULT;
++	}
++
++	dma_channel_init();
++
++#ifdef DMA_DEBUG
++	dma_dump_reg();
++#endif
++
++	spin_lock_init(&dma_lock);
++	INIT_LIST_HEAD(&dma_xfer_q);
++	INIT_LIST_HEAD(&dma_done_q);
++	
++	// Eileen , for linux kernel 2.6.24 , 20080424
++	//retval = request_irq(INTC_GDMAC_TC_BIT_INDEX, &dma_tc_isr, SA_INTERRUPT, "STAR DMA TC ISR", &dma_dev);
++	retval = request_irq(INTC_GDMAC_TC_BIT_INDEX, &dma_tc_isr, IRQF_DISABLED, "STAR DMA TC ISR", &dma_dev);
++	if (retval) {
++		printk("%s: unable to get IRQ %d (irqval=%d).\n", "STAR DMA", INTC_GDMAC_TC_BIT_INDEX, retval);
++		return retval;
++	}
++	// Eileen , for linux kernel 2.6.24 , 20080424
++	// old : retval = request_irq(INTC_GDMAC_ERROR_BIT_INDEX, &dma_err_isr, SA_INTERRUPT, "STAR DMA ERR ISR", &dma_dev);
++	retval = request_irq(INTC_GDMAC_ERROR_BIT_INDEX, &dma_err_isr, IRQF_DISABLED, "STAR DMA ERR ISR", &dma_dev);
++	if (retval) {
++		printk("%s: unable to get IRQ %d (irqval=%d).\n", "STAR DMA", INTC_GDMAC_ERROR_BIT_INDEX, retval);
++		free_irq(INTC_GDMAC_TC_BIT_INDEX, &dma_dev);
++		return retval;
++	}
++
++	return 0;
++}
++
++// Eileen , for linux kernel 2.6.24 , 20080425
++#ifdef STR8100_DMA_TEST
++	static int str8100_dmacopy_busywait_test(void);
++	static int str8100_dmacopy_llp_test(void);
++#endif
++
++
++static int __init str8100_dma_init(void)
++{
++	int retval;
++
++	printk("STR8100 DMA driver init\n");
++	retval = dma_init();
++#ifdef STR8100_DMA_TEST
++	if (retval == 0) {
++	       	// Eileen , for linux kernel 2.6.24 , 20080425
++		//move : static int str8100_dmacopy_busywait_test(void);
++		//move : static int str8100_dmacopy_llp_test(void);
++		(void)str8100_dmacopy_busywait_test();
++		(void)str8100_dmacopy_llp_test();
++	}
++#endif
++	return retval;
++}
++
++static void __exit str8100_dma_exit(void)
++{
++	return;
++}
++
++module_init(str8100_dma_init);
++module_exit(str8100_dma_exit);
++
++#ifdef STR8100_DMA_TEST
++#define MEMSIZE_K	64
++#define MEMSIZE		(MEMSIZE_K*1024)
++
++static int str8100_dmacopy_busywait_test(void)
++{
++	u8 *src;
++	u8 *dst;
++	int i;
++	int sjiffies;
++	int err_cnt = 0;
++
++	src = kmalloc(MEMSIZE, GFP_KERNEL);
++	if (!src) goto out;
++	dst = kmalloc(MEMSIZE, GFP_KERNEL);
++	if (!dst) {
++		kfree(src);
++		goto out;
++	}
++
++	memset(src, 0xA9, MEMSIZE);
++	memset(dst, 0, MEMSIZE);
++
++	printk("STR8100 DMA Busy Wait Testing...\n");
++
++	sjiffies = jiffies;
++	for (i = 0; i < 1024; i++) {
++		dma_memcpy_busy_wait(dst, src, MEMSIZE);
++	}
++
++	printk("STR8100 DMA Busy Wait Testing end\n");
++	if (memcmp(src, dst, MEMSIZE) == 0) {
++		printk("STR8100 DMA Busy Wait Testing success\n");
++		printk("STR8100 DMA Busy Wait Testing speed: %dMB/s\n", (u32)((MEMSIZE_K) * HZ/(jiffies - sjiffies)));
++	} else {
++		printk("STR8100 DMA Busy Wait Testing failed\n");
++		for (i = 0; i < MEMSIZE; i++) {
++			if (src[i] != dst[i]) {
++				err_cnt++;
++			}
++		}
++		printk("err_cnt: %d\n", err_cnt);
++	}
++
++	kfree(src);
++	kfree(dst);
++
++out:
++	return 0;
++}
++
++#define NUM_DMA_XFER		32
++#define NUM_DMA_VEC		32
++#define NUM_BYTES_PER_VEC	1024
++
++static dma_xfer_t dma_xfer_test[NUM_DMA_XFER];
++static u32 dma_xfer_finished;
++
++static u8 *src_vec[NUM_DMA_XFER];
++static u8 *dst_vec[NUM_DMA_XFER];
++
++extern void dma_copy(dma_xfer_t *dma_xfer);
++extern void dma_dump_reg(void);
++
++static void dma_copy_end(dma_xfer_t *dma_xfer, int err)
++{
++	int i;
++	int idx;
++
++	idx = (int)dma_xfer->private;
++	dma_xfer_finished++;
++
++	if (err) {
++		printk("STR8100 DMA Testing failed!!\n");
++	} else {
++		for (i = 0; i < NUM_DMA_VEC; i++) {
++			if (memcmp((src_vec[idx] + i * NUM_BYTES_PER_VEC), (dst_vec[idx] + i * NUM_BYTES_PER_VEC), NUM_BYTES_PER_VEC) == 0) {
++				printk("STR8100 DMA Testing success on xfer idx:%d started at offset: %04d:\n", idx, i * NUM_BYTES_PER_VEC);
++			} else {
++				int j;
++				u8 *psrc;
++				u8 *pdst;
++
++				psrc = src_vec[idx] + i * NUM_BYTES_PER_VEC;
++				pdst = dst_vec[idx] + i * NUM_BYTES_PER_VEC;
++
++				printk("STR8100 DMA Testing error started at offset: %04d\n", i * NUM_BYTES_PER_VEC);
++
++				for (j = 0; j < NUM_BYTES_PER_VEC; j++) {
++					if ((j % 16) == 0) {
++						printk("\n %08x: ", (u32)(psrc + j));
++					}
++					if (((j % 16) != 0) && ((j % 4) == 0)) {
++						printk(" ");
++					}
++					printk("%02x", psrc[j]);
++				}
++				printk("\n");
++	
++				for (j = 0; j < NUM_BYTES_PER_VEC; j++) {
++					if ((j % 16) == 0) {
++						printk("\n %08x: ", (u32)(pdst + j));
++					}
++					if (((j % 16) != 0) && ((j % 4) == 0)) {
++						printk(" ");
++					}
++					printk("%02x", pdst[j]);
++				}
++				printk("\n");
++			}
++		}
++	}
++
++	if (dma_xfer_finished == NUM_DMA_XFER) {
++		for (i = 0; i < NUM_DMA_XFER; i++) {
++			kfree(src_vec[i]);
++			kfree(dst_vec[i]);
++		}
++	}
++}
++
++static int str8100_dmacopy_llp_test(void)
++{
++	int i, j;
++
++	for (i = 0; i < NUM_DMA_XFER; i++) {
++		src_vec[i] = kmalloc(MEMSIZE, GFP_KERNEL);
++		if (!src_vec[i]) goto err_out;
++		dst_vec[i] = kmalloc(MEMSIZE, GFP_KERNEL);
++		if (!dst_vec[i]) goto err_out;
++		memset(src_vec[i], 0xA9, MEMSIZE);
++		memset(dst_vec[i], 0x00, MEMSIZE);
++		printk("dmacopy_llp src_vec[%d]: 0x%08x\n", i, (u32)src_vec[i]);
++		printk("dmacopy_llp dst_vec[%d]: 0x%08x\n", i, (u32)dst_vec[i]);
++	}
++
++	for (i = 0; i < NUM_DMA_XFER; i++) {
++		dma_xfer_test[i].nr_vec = NUM_DMA_VEC;
++		dma_xfer_test[i].dma_end_io = dma_copy_end;
++		dma_xfer_test[i].private = (void *)i;
++		for (j = 0; j < NUM_DMA_VEC; j++) {
++			dma_xfer_test[i].vec[j].src_addr = (u32)(src_vec[i] + (j * NUM_BYTES_PER_VEC));
++			dma_xfer_test[i].vec[j].dst_addr = (u32)(dst_vec[i] + (j * NUM_BYTES_PER_VEC));
++			dma_xfer_test[i].vec[j].size = NUM_BYTES_PER_VEC;
++			dma_xfer_test[i].vec[j].dst_sel = 0;
++			dma_xfer_test[i].vec[j].src_sel = 0;
++			dma_xfer_test[i].vec[j].dst_addr_ctl = 0;
++			dma_xfer_test[i].vec[j].src_addr_ctl = 0;
++			dma_xfer_test[i].vec[j].dst_width = DMAC_CH_DST_WIDTH_8BIT;
++			dma_xfer_test[i].vec[j].src_width = DMAC_CH_SRC_WIDTH_8BIT;
++		}
++	}
++
++	printk("STR8100 DMA Testing ...\n");
++
++	for (i = 0; i < NUM_DMA_XFER; i++) {
++		dma_copy(&dma_xfer_test[i]);
++	}
++
++	return 0;
++
++err_out:
++	for (i = 0; i < NUM_DMA_XFER; i++) {
++		if (src_vec[i])
++			kfree(src_vec[i]);
++		if (dst_vec[i])
++			kfree(dst_vec[i]);
++	}
++	return 0;
++}
++
++#endif // STR8100_DMA_TEST
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_gpio.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_gpio.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_gpio.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_gpio.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,855 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/miscdevice.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/sched.h>
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <mach/hardware.h>
++#include <asm/mach-types.h>
++
++#include <mach/star_powermgt.h>
++#include <mach/star_intc.h>
++#include <mach/star_misc.h>
++#include <mach/star_gpio.h>
++
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++
++#define MAX_GPIOA_LINE		32
++#define MAX_GPIOB_LINE		32
++#define PIN_INPUT 0
++#define PIN_OUTPUT 1
++
++#define PIN_TRIG_EDGE 0
++#define PIN_TRIG_LEVEL 1
++
++#define PIN_TRIG_SINGLE 0
++#define PIN_TRIG_BOTH 1
++
++#define PIN_TRIG_RISING 0
++#define PIN_TRIG_FALLING 1
++
++#define PIN_TRIG_HIGH 0
++#define PIN_TRIG_LOW 1
++void (*gpio_a_isr[MAX_GPIOA_LINE])(int i);
++void (*gpio_b_isr[MAX_GPIOB_LINE])(int i);
++
++#endif
++
++#if 0
++int __init_or_module gpio_direction_input(unsigned int);
++int __init_or_module gpio_direction_output(unsigned int, unsigned int);
++void gpio_set_value(unsigned int, unsigned int);
++int gpio_get_value(unsigned int);
++void str8100_gpio_a_set_edgeintr(void (*funcptr)(int), int, int, int);
++void str8100_gpio_b_set_edgeintr(void (*funcptr)(int),int,int, int);
++void str8100_gpio_a_set_levelintr(void (*funcptr)(int),int, int);
++void str8100_gpio_b_set_levelintr(void (*funcptr)(int),int, int);
++#endif
++
++/* 
++ * str8100_gpio_a_in - read Data Input Register(RO) of GPIO A
++ * @data: the target to store content of register
++ */
++int str8100_gpio_a_datain(volatile __u32 *data)
++{
++	HAL_GPIOA_READ_DATA_IN_STATUS(*data);
++	return 0;
++}
++
++/* 
++ * str8100_gpio_b_in - read Data Input Register(RO) of GPIO B
++ * @data: the target to store content of register
++ */
++int str8100_gpio_b_datain(volatile __u32 *data)
++{
++	HAL_GPIOB_READ_DATA_IN_STATUS(*data);
++	return 0;
++}
++
++/* str8100_gpio_a_out - write Data Output Register(RW) of GPIO A
++ * @data:
++ */
++int str8100_gpio_a_dataout(__u32 data)
++{
++	GPIOA_DATA_OUTPUT_REG = data;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_b_out - write Data Output Register(RW) of GPIO B
++ * @data:
++ */
++int str8100_gpio_b_out(__u32 data)
++{
++	GPIOB_DATA_OUTPUT_REG = data;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_a_read_direction - read Direction Register(RW) GPIO A
++ * @data:
++ */
++int str8100_gpio_a_read_direction(volatile __u32 *data)
++{
++	*data = GPIOA_DIRECTION_REG;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_b_read_direction - read Direction Register(RW) of GPIO B
++ * @data:
++ */
++int str8100_gpio_b_read_direction(volatile __u32 *data)
++{
++	*data = GPIOB_DIRECTION_REG;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_a_write_direction - write Direction Register(RW) of GPIO A
++ * @data:
++ */
++int str8100_gpio_a_write_direction(__u32 data)
++{
++	GPIOA_DIRECTION_REG = data;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_b_write_direction - write Direction Register(RW) of GPIO B
++ * @data:
++ */
++int str8100_gpio_b_write_direction(__u32 data)
++{
++	GPIOB_DIRECTION_REG = data;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_a_dataset - write Data Bit Set Register (W) of GPIO A
++ * @data:
++ *
++ * When write to this register and if some bits of GpioDataSet are 1,
++ * the corresponding bits in GpioDataOut register will be set to 1, 
++ * and the others will not be changed.
++ */
++int str8100_gpio_a_dataset(__u32 data)
++{
++	GPIOA_DATA_BIT_SET_REG = data;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_b_dataset - write Data Bit Set Register (W) of GPIO B
++ * @data:
++ */
++int str8100_gpio_b_dataset(__u32 data)
++{
++	GPIOB_DATA_BIT_SET_REG = data;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_a_dataclear - write Data Bit Clear Register (W) of GPIO A
++ * @data:
++ *
++ * When write to this register and if some bits of GpioDataClear are 1,
++ * the corresponding bits in GpioDataOut register will be cleard, 
++ * and the others will not be changed.
++ */
++int str8100_gpio_a_dataclear(__u32 data)
++{
++	GPIOA_DATA_BIT_CLEAR_REG = data;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_b_dataclear - write Data Bit Clear Register (W) of GPIO B
++ * @data:
++ */
++int str8100_gpio_b_dataclear(__u32 data)
++{
++	GPIOB_DATA_BIT_CLEAR_REG = data;
++	return 0;
++}
++/*
++Read String into Buffer, Max String buffer is 100
++*/
++ssize_t readstring(char *buff, const char *buf, size_t count){
++    	int i=0;
++        if (count) {
++                char c;
++
++            for(i=0;i<count&&i<100;i++){
++                if (get_user(c, buf+i))
++                        return -EFAULT;
++                    buff[i] = c;
++            }
++                buff[i]=0;
++        }
++        return count;
++
++}
++
++#ifdef CONFIG_STR8100_GPIO_GENERIC_INTERFACE
++static int str8100_gpio_proc(char *page, char **start,  off_t off, int count, int *eof, void *data)
++{
++	int num = 0;
++
++	num += sprintf(page+num, "********** GPIO Group A **********\n");
++	
++	num += sprintf(page+num, "GPIO IN                : %08x \n", GPIOA_DATA_INPUT_REG);
++
++	num += sprintf(page+num, "GPIO Direction         : %08x \n", GPIOA_DIRECTION_REG);
++
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++	num += sprintf(page+num, "GPIO Interrupt Enable  : %08x \n", GPIOA_INTERRUPT_ENABLE_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt Raw     : %08x \n", GPIOA_INTERRUPT_RAW_STATUS_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt Trigger : %08x \n", GPIOA_INTERRUPT_TRIGGER_METHOD_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt Both    : %08x \n", GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt RiseNeg : %08x \n", GPIOA_INTERRUPT_TRIGGER_TYPE_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt MASKED  : %08x \n", GPIOA_INTERRUPT_MASK_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt MASKEDST: %08x \n", GPIOA_INTERRUPT_MASKED_STATUS_REG);
++#endif	
++
++	num+= sprintf(page+num, "********** GPIO Group B **********\n");
++	
++	num += sprintf(page+num, "GPIO IN                : %08x \n", GPIOB_DATA_INPUT_REG);
++
++	num += sprintf(page+num, "GPIO Direction         : %08x \n", GPIOB_DIRECTION_REG);
++
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++	num += sprintf(page+num, "GPIO Interrupt Enable  : %08x \n", GPIOB_INTERRUPT_ENABLE_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt Raw     : %08x \n", GPIOB_INTERRUPT_RAW_STATUS_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt Trigger : %08x \n", GPIOB_INTERRUPT_TRIGGER_METHOD_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt Both    : %08x \n", GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt RiseNeg : %08x \n", GPIOB_INTERRUPT_TRIGGER_TYPE_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt MASKED  : %08x \n", GPIOB_INTERRUPT_MASK_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt MASKEDST: %08x \n", GPIOB_INTERRUPT_MASKED_STATUS_REG);
++#endif	
++
++	return num;
++}
++#endif
++
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++static irqreturn_t str8100_gpio_irq_handler(int this_irq, void *dev_id /*, struct pt_regs *regs */)
++{
++	unsigned int volatile    status;
++	int i;
++
++	// Clean System irq status
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++
++	HAL_GPIOA_READ_INTERRUPT_MASKED_STATUS(status);
++	for (i = 0; i < MAX_GPIOA_LINE; i++) {   
++		if (status & (1 << i))  {   		/* interrupt is detected and not masked */
++			if (gpio_a_isr[i] != NULL) {
++				gpio_a_isr[i](i);
++			}
++		}    
++	}  
++    HAL_GPIOA_CLEAR_INTERRUPT(status);
++
++	HAL_GPIOB_READ_INTERRUPT_MASKED_STATUS(status);
++	for (i = 0; i < MAX_GPIOB_LINE; i++) {   
++		if (status & (1 << i)) {			/* interrupt is detected and not masked */
++			if (gpio_b_isr[i] != NULL) {
++				gpio_b_isr[i](i);
++			}
++		}    
++	}   
++    HAL_GPIOB_CLEAR_INTERRUPT(status);
++
++	/* Unmask Intc Interrupt Status */
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++	return IRQ_HANDLED;
++}
++
++int intr_a_count=0;
++int intr_b_count=0;
++/*  
++ * Setup GPIOA for Edge Trigger Interrupt mode 
++ */
++void str8100_gpio_a_set_edgeintr(void (*funcptr)(int), int trig_both, int trig_rising, int gpio_pin)
++{
++	u32 gpio_index = (0x1 << gpio_pin);
++	
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIOA_LINE) {
++		HAL_GPIOA_SET_DIRECTION_INPUT(gpio_index);
++
++		if (trig_both == PIN_TRIG_BOTH) {
++			/* Set Trigger Both */
++			HAL_GPIOA_SET_INTERRUPT_BOTH_EDGE_TRIGGER_MODE(gpio_index);	
++		}
++		else if (trig_both == PIN_TRIG_SINGLE) {
++			/* Set Single Rising/Falling Edge Trigger */
++			if (trig_rising == PIN_TRIG_RISING) {
++				HAL_GPIOA_SET_INTERRUPT_SINGLE_RISING_EDGE_TRIGGER_MODE(gpio_index);
++			}
++			else if (trig_rising == PIN_TRIG_FALLING) {
++				HAL_GPIOA_SET_INTERRUPT_SINGLE_FALLING_EDGE_TRIGGER_MODE(gpio_index);
++			}
++			else {
++				printk("Trigger rising/falling error.\n");
++				return;
++			}
++		}
++		else
++		{
++			printk("Trigger both/single error.\n");
++			return;
++		}
++
++		gpio_a_isr[gpio_pin] = funcptr;
++
++		/* Enable Interrupt */
++		HAL_GPIOA_ENABLE_INTERRUPT(gpio_index);
++	}
++}
++
++/*  
++ * Setup GPIOB for Edge Trigger Interrupt mode 
++ */
++void str8100_gpio_b_set_edgeintr(void (*funcptr)(int),int trig_both,int trig_rising, int gpio_pin)
++{
++	u32 gpio_index = (0x1 << gpio_pin);
++	
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIOA_LINE) {
++		HAL_GPIOB_SET_DIRECTION_INPUT(gpio_index);
++
++		if (trig_both == PIN_TRIG_BOTH) {
++			/* Set Trigger Both */
++			HAL_GPIOB_SET_INTERRUPT_BOTH_EDGE_TRIGGER_MODE(gpio_index);	
++		}
++		else if (trig_both == PIN_TRIG_SINGLE) {
++			/* Set Single Rising/Falling Edge Trigger */
++			if (trig_rising == PIN_TRIG_RISING) {
++				HAL_GPIOB_SET_INTERRUPT_SINGLE_RISING_EDGE_TRIGGER_MODE(gpio_index);
++			}
++			else if (trig_rising == PIN_TRIG_FALLING) {
++				HAL_GPIOB_SET_INTERRUPT_SINGLE_FALLING_EDGE_TRIGGER_MODE(gpio_index);
++			}
++			else {
++				printk("Trigger rising/falling error.\n");
++				return;
++			}
++		}
++		else {
++			printk("Trigger both/single error.\n");
++			return;
++		}
++
++		gpio_b_isr[gpio_pin] = funcptr;
++
++		/* Enable Interrupt */
++		HAL_GPIOB_ENABLE_INTERRUPT(gpio_index);
++	}
++}
++
++/*  
++ * Clear GPIOA Trigger Interrupt
++ */
++void str8100_gpio_a_clear_intr(int gpio_pin)
++{
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIOA_LINE) {
++		/* Unregister isr of GPIOA[gpio_pin] */	
++		gpio_a_isr[gpio_pin] = NULL;	
++		/* Disable Interrupt */
++		HAL_GPIOA_DISABLE_INTERRUPT(0x1 << gpio_pin);
++	}
++}
++
++/*  
++ * Clear GPIOB Trigger Interrupt
++ */
++void str8100_gpio_b_clear_intr(int gpio_pin)
++{
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIOB_LINE) {
++		/* Unregister isr of GPIOB[gpio_pin] */
++		gpio_b_isr[gpio_pin] = NULL;			
++		/* Disable Interrupt */
++		HAL_GPIOB_DISABLE_INTERRUPT(0x1 << gpio_pin);
++	}
++}
++
++/*  
++ * Setup GPIOA for LEVEL Trigger Interrupt mode 
++ */
++void str8100_gpio_a_set_levelintr(void (*funcptr)(int),int trig_level, int gpio_pin)
++{
++	u32 gpio_index = (0x1 << gpio_pin);
++
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIOA_LINE) {
++		HAL_GPIOA_SET_DIRECTION_INPUT(gpio_index);
++
++		/* Set Trigger High/Low */
++		if (trig_level == PIN_TRIG_HIGH) {
++			HAL_GPIOA_SET_INTERRUPT_HIGH_LEVEL_TRIGGER_MODE(gpio_index);
++		}
++		else if (trig_level == PIN_TRIG_LOW) {
++			HAL_GPIOA_SET_INTERRUPT_LOW_LEVEL_TRIGGER_MODE(gpio_index);
++		}
++		else {
++			printk("Trigger level error.\n");
++			return;
++		}
++
++		gpio_a_isr[gpio_pin] = funcptr;
++
++		/* Enable Interrupt */
++		HAL_GPIOA_ENABLE_INTERRUPT(gpio_index);
++	}
++}
++
++/*  
++ * Setup GPIO for LEVEL Triggle Interrupt mode 
++ */
++void str8100_gpio_b_set_levelintr(void (*funcptr)(int),int trig_level, int gpio_pin)
++{
++	u32 gpio_index = (0x1 << gpio_pin);
++
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIOB_LINE) {
++		HAL_GPIOB_SET_DIRECTION_INPUT(gpio_index);
++
++		/* Set Trigger High/Low */
++		if (trig_level == PIN_TRIG_HIGH) {
++			HAL_GPIOB_SET_INTERRUPT_HIGH_LEVEL_TRIGGER_MODE(gpio_index);
++		}
++		else if (trig_level == PIN_TRIG_LOW) {
++			HAL_GPIOB_SET_INTERRUPT_LOW_LEVEL_TRIGGER_MODE(gpio_index);
++		}
++		else {
++			printk("Trigger level error.\n");
++			return;
++		}
++
++		gpio_b_isr[gpio_pin] = funcptr;
++
++		/* Enable Interrupt */
++		HAL_GPIOB_ENABLE_INTERRUPT(gpio_index);
++	}
++}
++
++EXPORT_SYMBOL(str8100_gpio_a_set_edgeintr);
++EXPORT_SYMBOL(str8100_gpio_a_clear_intr);
++EXPORT_SYMBOL(str8100_gpio_a_set_levelintr);
++EXPORT_SYMBOL(str8100_gpio_b_set_edgeintr);
++EXPORT_SYMBOL(str8100_gpio_b_clear_intr);
++EXPORT_SYMBOL(str8100_gpio_b_set_levelintr);
++
++/*  
++ * Display GPIO information at /proc/str9100/gpio
++ */
++
++#ifdef STR8100_GPIO_INTERRUPT_TEST
++void str8100_gpio_intr_test(int i)
++{
++	printk("GPIO Interrupt Service Single Active : %d \n",i);
++}
++#endif
++
++#endif
++
++#ifdef CONFIG_STR8100_GPIO_GENERIC_INTERFACE
++/***********************************************************************
++ * The STR8100 has GPIOA(32) and GPIOB(32) total 64 GPIO. For the
++ * generic GPIO interface, the GPIO pin number count from GPIOA to GPIOB.
++ * For example:
++ *      0 -> GPIOA[0]
++ *      1 -> GPIOA[1]
++ *     ......
++ *     31 -> GPIOA[31]
++ *     32 -> GPIOB[0]
++ *     33 -> GPIOB[1]
++ *     ......
++ *     63 -> GPIOB[31]
++ **********************************************************************/
++
++#define GPIOA_PIN_NO	32
++#define GPIOB_PIN_NO	32
++#define MAX_GPIO_NO	(GPIOA_PIN_NO + GPIOB_PIN_NO)
++
++/*
++ * Configure the GPIO line as an input.
++ */
++int __init_or_module gpio_direction_input(unsigned int pin)
++{
++	volatile __u32 reg;
++	unsigned long flags;
++
++	if (pin >= MAX_GPIO_NO)
++		return -EINVAL;
++
++        local_irq_save(flags);
++
++	/* Clear register bit to set as input pin. */
++	if (pin < GPIOA_PIN_NO)
++	{
++		/* GPIOA */
++		reg = GPIOA_DIRECTION_REG;
++		reg &= ~(1 << pin);
++		GPIOA_DIRECTION_REG = reg;
++	}
++	else
++	{
++		/* GPIOB */
++		reg = GPIOB_DIRECTION_REG;
++		reg &= ~(1 << (pin - GPIOA_PIN_NO));
++		GPIOB_DIRECTION_REG = reg;
++	}
++
++        local_irq_restore(flags);
++
++        return 0;
++}
++//EXPORT_SYMBOL(gpio_direction_input);
++
++/*
++ * Configure the GPIO line as an output, with default state.
++ */
++int __init_or_module gpio_direction_output(unsigned int pin, unsigned int state)
++{
++	volatile __u32 reg;
++	unsigned long flags;
++	if (pin >= MAX_GPIO_NO)
++		return -EINVAL;
++
++        local_irq_save(flags);
++
++	if (pin < GPIOA_PIN_NO)
++	{
++		/* GPIOA */
++		/* Set register bit to set as output pin. */
++		reg = GPIOA_DIRECTION_REG;
++		reg |= (1 << pin);
++		GPIOA_DIRECTION_REG = reg;
++
++		if (state)
++			GPIOA_DATA_BIT_SET_REG = (1 << pin);
++		else
++			GPIOA_DATA_BIT_CLEAR_REG = (1 << pin);
++
++	}
++	else
++	{
++		/* GPIOB */
++		/* Set register bit to set as output pin. */
++		reg = GPIOB_DIRECTION_REG;
++		reg |= (1 << (pin - GPIOA_PIN_NO));
++		GPIOB_DIRECTION_REG = reg;
++
++		if (state)
++			GPIOB_DATA_BIT_SET_REG = (1 << (pin - GPIOA_PIN_NO));
++		else
++			GPIOB_DATA_BIT_CLEAR_REG = (1 << (pin - GPIOA_PIN_NO));
++	}
++
++        local_irq_restore(flags);
++
++        return 0;
++}
++EXPORT_SYMBOL(gpio_direction_output);
++
++
++/*
++ * Set the state of an output GPIO line.
++ */
++void gpio_set_value(unsigned int pin, unsigned int state)
++{
++	if (pin >= MAX_GPIO_NO)
++		return;
++
++	if (pin < GPIOA_PIN_NO)
++	{
++		/* GPIOA */
++		if (state)
++			GPIOA_DATA_BIT_SET_REG = (1 << pin);
++		else
++			GPIOA_DATA_BIT_CLEAR_REG = (1 << pin);
++
++	}
++	else
++	{
++		/* GPIOB */
++		if (state)
++			GPIOB_DATA_BIT_SET_REG = (1 << (pin - GPIOA_PIN_NO));
++		else
++			GPIOB_DATA_BIT_CLEAR_REG = (1 << (pin - GPIOA_PIN_NO));
++	}
++}
++EXPORT_SYMBOL(gpio_set_value);
++
++
++/*
++ * Read the state of a GPIO line.
++ */
++int gpio_get_value(unsigned int pin)
++{
++	volatile __u32 reg;
++	bool bret = 0;
++
++	if (pin >= MAX_GPIO_NO)
++		return -EINVAL;
++
++	if (pin < GPIOA_PIN_NO)
++	{
++		/* GPIOA */
++		str8100_gpio_a_datain(&reg);
++		bret = (reg & (1 << pin)) != 0;
++	}
++	else
++	{
++		/* GPIOB */
++		str8100_gpio_b_datain(&reg);
++		bret = (reg & (1 << (pin - GPIOA_PIN_NO))) != 0;
++	}
++	
++	return bret;
++}
++EXPORT_SYMBOL(gpio_get_value);
++
++
++/*
++ * Map GPIO line to IRQ number.
++ */
++int gpio_to_irq(unsigned int pin)
++{
++	return INTC_GPIO_EXTERNAL_INT_BIT_INDEX;
++}
++EXPORT_SYMBOL(gpio_to_irq);
++
++
++/*
++ * INVALID
++ */
++int irq_to_gpio(unsigned int irq)
++{
++	return -EINVAL;
++}
++EXPORT_SYMBOL(irq_to_gpio);
++
++#endif /* CONFIG_STR8100_GPIO_GENREIC_INTERFACE */
++
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++static void gpio_a_isr_test(int i)
++{
++	unsigned int volatile status = 0;
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++	printk("gpio_a_isr_test, count:%d\n",intr_a_count+1);
++	status = GPIOA_INTERRUPT_MASKED_STATUS_REG;
++	HAL_GPIOA_CLEAR_INTERRUPT(status);
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++
++	intr_a_count++;
++	if (intr_a_count >= 4) {
++		str8100_gpio_a_clear_intr(i);
++		intr_a_count = 0;
++	}
++
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++}
++
++static void gpio_b_isr_test(int i)
++{
++	unsigned int volatile status = 0;
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++	printk("gpio_b_isr_test, count:%d\n",intr_b_count+1);
++	status = GPIOB_INTERRUPT_MASKED_STATUS_REG;
++	HAL_GPIOB_CLEAR_INTERRUPT(status);
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++
++	intr_b_count++;
++	if (intr_b_count >= 4) {
++		str8100_gpio_b_clear_intr(i);
++		intr_b_count = 0;
++	}
++
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++}
++#endif
++
++#ifdef CONFIG_STR8100_GPIO_GENERIC_INTERFACE
++static ssize_t str8100_gpio_write_proc(struct file *file, const char __user *buffer,
++			   ssize_t count, void *data){
++	int pin = 0,state =0;
++	char read_buff[100],buf_cmd[100],buf_param1[100],buf_param2[100],buf_param3[100],buf_param4[100];
++	readstring((char *)read_buff,(const char *)buffer,count);
++	sscanf(read_buff,"%s %s %s %s %s\n",(char *)&buf_cmd,(char *)&buf_param1\
++									   ,(char *)&buf_param2, (char *)&buf_param3, (char *)&buf_param4);
++	//printk("buf_cmd:%s buf_param1:%s buf_param2:%s buf_param2:%s \n", buf_cmd,buf_param1,buf_param2,buf_param3);
++	if(strcmp(buf_cmd,"direct") == 0)
++		if(strcmp(buf_param1,"input") == 0){
++			sscanf(buf_param2, "%d", &pin);
++			//printk("direction input pin=%d \n",pin);
++			gpio_direction_input(pin);
++		}
++	if(strcmp(buf_cmd,"direct") == 0)
++		if(strcmp(buf_param1,"output") == 0){
++			sscanf(buf_param2, "%d", &pin);
++			sscanf(buf_param3, "%d", &state);
++			//printk("direction output pin=%d state=%d  \n",pin,state);
++			gpio_direction_output(pin,state);
++		}
++	if(strcmp(buf_cmd,"set") == 0)
++		if(strcmp(buf_param1,"value") == 0){
++			sscanf(buf_param2, "%d", &pin);
++			sscanf(buf_param3, "%d", &state);
++			printk("set value pin=%d state=%d  \n",pin,state);
++			gpio_set_value(pin,state);
++		}
++	if(strcmp(buf_cmd,"get") == 0)
++		if(strcmp(buf_param1,"value") == 0){
++			sscanf(buf_param2, "%d", &pin);
++			state=gpio_get_value(pin);
++			printk("get value pin=%d state=%d \n",pin,state);
++		}
++
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++	if(strcmp(buf_cmd,"trig") == 0){
++		if(strcmp(buf_param1,"edge") == 0){
++			if(strcmp(buf_param2,"both") == 0){
++				sscanf(buf_param3, "%d", &pin);
++				if (pin < GPIOA_PIN_NO)
++					str8100_gpio_a_set_edgeintr(&gpio_a_isr_test, 1, 0, pin);
++				else
++					str8100_gpio_b_set_edgeintr(&gpio_b_isr_test, 1, 0, pin-GPIOA_PIN_NO);		
++			}
++			if(strcmp(buf_param2,"single") == 0){
++				if(strcmp(buf_param3,"rising") == 0){
++					sscanf(buf_param4, "%d", &pin);
++					if (pin < GPIOA_PIN_NO)
++						str8100_gpio_a_set_edgeintr(&gpio_a_isr_test, 0, 0, pin);
++					else
++						str8100_gpio_b_set_edgeintr(&gpio_b_isr_test, 0, 0, pin-GPIOA_PIN_NO);
++				}
++				if(strcmp(buf_param3,"falling") == 0){
++					sscanf(buf_param4, "%d", &pin);
++					if (pin < GPIOA_PIN_NO)
++						str8100_gpio_a_set_edgeintr(&gpio_a_isr_test, 0, 1, pin);
++					else
++						str8100_gpio_b_set_edgeintr(&gpio_b_isr_test, 0, 1, pin-GPIOA_PIN_NO);
++				}		
++			}
++		}
++		if(strcmp(buf_param1,"level") == 0){
++			if(strcmp(buf_param2,"high") == 0){
++				sscanf(buf_param3, "%d", &pin);
++				if (pin < GPIOA_PIN_NO)
++					str8100_gpio_a_set_levelintr(&gpio_a_isr_test, 0, pin);
++				else
++					str8100_gpio_b_set_levelintr(&gpio_b_isr_test, 0, pin-GPIOA_PIN_NO);
++			}
++			if(strcmp(buf_param2,"low") == 0){
++				sscanf(buf_param3, "%d", &pin);
++				if (pin < GPIOA_PIN_NO)
++					str8100_gpio_a_set_levelintr(&gpio_a_isr_test, 1, pin);
++				else
++					str8100_gpio_b_set_levelintr(&gpio_b_isr_test, 1, pin-GPIOA_PIN_NO);
++			}
++		}
++	}
++#endif
++		
++	return count;
++	
++}
++
++static struct proc_dir_entry *proc_str8100_gpio;
++#endif
++extern void str8100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++
++int __init str8100_gpio_init(void)
++{
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++	u32 i, ret;
++#endif
++
++	//proc_str8100_gpio = create_proc_read_entry("str8100/gpio", 0, NULL, str8100_gpio_proc, NULL) ;
++#ifdef CONFIG_STR8100_GPIO_GENERIC_INTERFACE
++	proc_str8100_gpio = create_proc_entry("str8100/gpio", S_IFREG | S_IRUGO, NULL) ;
++	proc_str8100_gpio->read_proc = str8100_gpio_proc;
++	proc_str8100_gpio->write_proc = str8100_gpio_write_proc;
++#endif
++
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++	for (i = 0; i < MAX_GPIOA_LINE; i++) {
++		gpio_a_isr[i] = NULL;
++	}
++	for (i = 0; i < MAX_GPIOB_LINE; i++) {
++		gpio_b_isr[i] = NULL;
++	}
++
++	/* Clear All Interrupt Status */
++	HAL_GPIOA_CLEAR_INTERRUPT(0xFFFFFFFF);
++	HAL_GPIOB_CLEAR_INTERRUPT(0xFFFFFFFF);
++	str8100_set_interrupt_trigger(INTC_GPIO_EXTERNAL_INT_BIT_INDEX, INTC_EDGE_TRIGGER, INTC_RISING_EDGE);
++	ret = request_irq(INTC_GPIO_EXTERNAL_INT_BIT_INDEX, str8100_gpio_irq_handler, 0, "str8100_gpio", 0);
++	if (ret < 0) {
++		printk("request_irq fail : %d \n", ret);
++		return 0;
++	} else {
++		printk("GPIO interrupt handler install ok. \n");
++	}
++#endif
++#ifdef STR8100_GPIO_INTERRUPT_TEST
++	str8100_gpio_a_set_edgeintr(&str8100_gpio_intr_test, PIN_TRIG_SINGLE, PIN_TRIG_RISING, 0);
++	str8100_gpio_a_set_levelintr(&str8100_gpio_intr_test, PIN_TRIG_HIGH, 1);
++#endif
++
++	return 0;
++}	
++
++void __exit str8100_gpio_exit(void)
++{
++	free_irq(INTC_GPIO_EXTERNAL_INT_BIT_INDEX, 0);
++}
++
++module_init(str8100_gpio_init);
++module_exit(str8100_gpio_exit);
++
++MODULE_LICENSE("GPL");
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_hsdma.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_hsdma.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_hsdma.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_hsdma.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,439 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/pci.h>
++#include <asm/io.h>
++#include <asm/delay.h>
++#include <mach/star_intc.h>
++#include <mach/star_hsdmac.h>
++
++//#define HSDMA_DEBUG
++#define STR8100_HSDMA_TEST
++
++#define HSDMA_MIN_XFER_SIZE		1024
++#define HSDMA_XFER_MAX_Q_LEN		32
++
++typedef struct
++{
++	struct list_head	lh;
++	hsdma_xfer_t		*xfer;
++	hsdma_llp_descr_t	*llp_descr;
++	u32			llp_descr_dma;
++	int			done_status;
++} hsdma_job_t;
++
++static u8 hsdma_dev;
++static spinlock_t hsdma_lock;
++static u8 hsdma_busy;
++static unsigned int hsdma_xfer_q_len;
++static unsigned int hsdma_done_q_len;
++static struct list_head hsdma_xfer_q;
++static struct list_head hsdma_done_q;
++static hsdma_job_t *hsdma_running_job;
++
++static void *hsdma_mem_pool;
++static u32 hsdma_mem_pool_dma;
++
++static hsdma_job_t hsdma_job_pool[HSDMA_XFER_MAX_Q_LEN];
++static struct list_head hsdma_job_q;
++static spinlock_t hsdma_job_q_lock;
++
++static void hsdma_process_xfer_job(void *data);
++static void hsdma_process_done_job(void *data);
++
++// Eileen , for linux kernel 2.6.24 , 20080425
++//static DECLARE_WORK(hsdma_xfer_task, hsdma_process_xfer_job, (void *)&hsdma_xfer_q);
++//static DECLARE_WORK(hsdma_done_task, hsdma_process_done_job, (void *)&hsdma_done_q);
++static DECLARE_WORK(hsdma_xfer_task, hsdma_process_xfer_job);
++static DECLARE_WORK(hsdma_done_task, hsdma_process_done_job);
++
++static int hsdma_job_q_init(void)
++{
++	int i;
++
++	hsdma_mem_pool = (void *)pci_alloc_consistent(NULL,
++		(HSDMA_XFER_MAX_Q_LEN * MAX_HSDMA_VEC * sizeof(hsdma_llp_descr_t)),
++	       	&hsdma_mem_pool_dma);
++
++	if (hsdma_mem_pool == NULL) {
++		return -1;
++	}
++
++	INIT_LIST_HEAD(&hsdma_job_q);
++	for (i = 0; i < HSDMA_XFER_MAX_Q_LEN; i++) {
++		INIT_LIST_HEAD(&hsdma_job_pool[i].lh);
++		hsdma_job_pool[i].llp_descr = (hsdma_llp_descr_t *)(hsdma_mem_pool + (i * (MAX_HSDMA_VEC * sizeof(hsdma_llp_descr_t))));
++		hsdma_job_pool[i].llp_descr_dma = hsdma_mem_pool_dma + (i * (MAX_HSDMA_VEC * sizeof(hsdma_llp_descr_t)));
++		list_add_tail(&hsdma_job_pool[i].lh, &hsdma_job_q);
++	}
++
++	return 0;
++}
++
++static hsdma_job_t *hsdma_job_alloc(void)
++{
++	hsdma_job_t *job;
++	unsigned long flags;
++
++	spin_lock_irqsave(&hsdma_job_q_lock, flags);
++	if (list_empty(&hsdma_job_q)) {
++		job = NULL;
++	} else {
++		job = list_entry(hsdma_job_q.next, hsdma_job_t, lh);
++		list_del_init(&job->lh);
++	}
++	spin_unlock_irqrestore(&hsdma_job_q_lock, flags);
++
++	return job;
++}
++
++static void hsdma_job_free(hsdma_job_t *job)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&hsdma_job_q_lock, flags);
++	list_add(&job->lh, &hsdma_job_q);
++	spin_unlock_irqrestore(&hsdma_job_q_lock, flags);
++}
++
++#ifdef HSDMA_DEBUG
++void hsdma_dump_reg(void)
++{
++	printk("HSDMAC_CONTROL_STATUS_REG:	0x%08x\n", HSDMAC_CONTROL_STATUS_REG);
++	printk("HSDMAC_MASTER0_ADDR_REG:	0x%08x\n", HSDMAC_MASTER0_ADDR_REG);
++	printk("HSDMAC_MASTER1_ADDR_REG:	0x%08x\n", HSDMAC_MASTER1_ADDR_REG);
++	printk("HSDMAC_LLP_REG:			0x%08x\n", HSDMAC_LLP_REG);
++	printk("HSDMAC_TOT_SIZE_REG:		0x%08x\n", HSDMAC_TOT_SIZE_REG);
++}
++#endif
++
++void hsdma_copy(hsdma_xfer_t *hsdma_xfer)
++{
++	hsdma_job_t *hsdma_job;
++	unsigned long flags;
++	int i;
++
++	if (hsdma_xfer_q_len > HSDMA_XFER_MAX_Q_LEN) {
++		hsdma_xfer->hsdma_end_io(hsdma_xfer, HSDMAC_RESPONSE_ERR);
++		return;
++	}
++
++	hsdma_job = hsdma_job_alloc();
++	if (hsdma_job == NULL) {
++		hsdma_xfer->hsdma_end_io(hsdma_xfer, HSDMAC_RESPONSE_ERR);
++		return;
++	}
++
++	memset(hsdma_job->llp_descr, 0, (hsdma_xfer->nr_vec * sizeof(hsdma_llp_descr_t)));
++	for (i = 0; i < hsdma_xfer->nr_vec; i++) {
++		if ((hsdma_xfer->vec[i].src_addr & 0x3) ||
++		    (hsdma_xfer->vec[i].dst_addr & 0x3) ||
++		    (hsdma_xfer->vec[i].size & 0x3)) {
++			hsdma_xfer->hsdma_end_io(hsdma_xfer, HSDMAC_RESPONSE_ERR);
++			hsdma_job_free(hsdma_job);
++			return;
++		}
++		hsdma_job->llp_descr[i].src_addr = (u32)virt_to_phys((void *)hsdma_xfer->vec[i].src_addr);
++		hsdma_job->llp_descr[i].dst_addr = (u32)virt_to_phys((void *)hsdma_xfer->vec[i].dst_addr);
++		hsdma_job->llp_descr[i].tot_size = (hsdma_xfer->vec[i].size >> 2) & 0xFFF;
++		hsdma_job->llp_descr[i].data_direction = hsdma_xfer->vec[i].data_direction;
++		if (i == (hsdma_xfer->nr_vec - 1)) {
++			hsdma_job->llp_descr[i].llp = 0;
++			hsdma_job->llp_descr[i].tc_mask = 0;
++		} else {
++			hsdma_job->llp_descr[i].llp = (u32)(hsdma_job->llp_descr_dma + ((i + 1) * sizeof(hsdma_llp_descr_t)));
++			hsdma_job->llp_descr[i].tc_mask = 1;
++		}
++		// Eileen , for linux kernel 2.6.24 , 20080425
++		//old : consistent_sync((void *)hsdma_xfer->vec[i].src_addr, hsdma_xfer->vec[i].size, PCI_DMA_TODEVICE);
++		//old : consistent_sync((void *)hsdma_xfer->vec[i].dst_addr, hsdma_xfer->vec[i].size, PCI_DMA_FROMDEVICE);
++		dma_cache_maint((void *)hsdma_xfer->vec[i].src_addr, hsdma_xfer->vec[i].size, PCI_DMA_TODEVICE);
++		dma_cache_maint((void *)hsdma_xfer->vec[i].dst_addr, hsdma_xfer->vec[i].size, PCI_DMA_FROMDEVICE);
++#ifdef HSDMA_DEBUG
++		printk("src_addr: 0x%08x\n", hsdma_job->llp_descr[i].src_addr);
++		printk("dst_addr: 0x%08x\n", hsdma_job->llp_descr[i].dst_addr);
++		printk("llp:      0x%08x\n", hsdma_job->llp_descr[i].llp);
++		printk("tot_size: 0x%08x\n", hsdma_job->llp_descr[i].tot_size);
++		printk("data_dir: 0x%08x\n", hsdma_job->llp_descr[i].data_direction);
++		printk("tc_mask:  0x%08x\n", hsdma_job->llp_descr[i].tc_mask);
++#endif
++	}
++
++	hsdma_job->xfer = hsdma_xfer;
++	hsdma_job->done_status = 0;
++
++	spin_lock_irqsave(&hsdma_lock, flags);
++	list_add_tail(&hsdma_job->lh, &hsdma_xfer_q);
++	hsdma_xfer_q_len++;
++	spin_unlock_irqrestore(&hsdma_lock, flags);
++
++	if (!hsdma_busy) {
++		schedule_work(&hsdma_xfer_task);
++	}
++}
++EXPORT_SYMBOL(hsdma_copy);
++
++static void hsdma_process_xfer_job(void *data)
++{
++	hsdma_job_t *hsdma_job;
++	unsigned long flags;
++
++	spin_lock_irqsave(&hsdma_lock, flags);
++	hsdma_job = list_entry(hsdma_xfer_q.next, hsdma_job_t, lh);
++	if (hsdma_job) {
++		list_del_init(&hsdma_job->lh);
++		hsdma_running_job = hsdma_job;
++		hsdma_xfer_q_len--;
++		hsdma_busy = 1;
++		if (hsdma_job->llp_descr[0].data_direction == HSDMAC_MASTER0_TO_MASTER1) {
++			HSDMAC_MASTER0_ADDR_REG = hsdma_job->llp_descr[0].src_addr;
++			HSDMAC_MASTER1_ADDR_REG = hsdma_job->llp_descr[0].dst_addr;
++			HSDMAC_TOT_SIZE_REG &= ~(0x1 << 29);
++		} else {
++			HSDMAC_MASTER0_ADDR_REG = hsdma_job->llp_descr[0].dst_addr;
++			HSDMAC_MASTER1_ADDR_REG = hsdma_job->llp_descr[0].src_addr;
++			HSDMAC_TOT_SIZE_REG |= (0x1 << 20);
++		}
++		HSDMAC_LLP_REG = (u32)hsdma_job->llp_descr[0].llp;
++		HSDMAC_TOT_SIZE_REG |= hsdma_job->llp_descr[0].tot_size;
++		if (hsdma_job->llp_descr[0].tc_mask) {
++			HSDMAC_TOT_SIZE_REG |= (0x1 << 28);
++		} else {
++			HSDMAC_TOT_SIZE_REG &= ~(0x1 << 28);
++		}
++		HAL_HSDMAC_ENABLE();
++	}
++	spin_unlock_irqrestore(&hsdma_lock, flags);
++}
++
++static void hsdma_process_done_job(void *data)
++{
++	hsdma_job_t *hsdma_job;
++	struct list_head *l, *t;
++	unsigned long flags;
++
++	spin_lock_irqsave(&hsdma_lock, flags);
++	list_for_each_safe(l, t, &hsdma_done_q) {
++		hsdma_job = list_entry(l, hsdma_job_t, lh);
++		list_del_init(&hsdma_job->lh);
++		hsdma_done_q_len--;
++		spin_unlock_irqrestore(&hsdma_lock, flags);
++		hsdma_job->xfer->hsdma_end_io(hsdma_job->xfer, hsdma_job->done_status);
++		hsdma_job_free(hsdma_job);
++		spin_lock_irqsave(&hsdma_lock, flags);
++	}
++	spin_unlock_irqrestore(&hsdma_lock, flags);
++}
++
++// Eileen , for linux kernel 2.6.24 , 20080425
++//old : irqreturn_t hsdma_isr(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t hsdma_isr(int irq, void *dev_id)
++{
++	hsdma_job_t *hsdma_job;
++
++	hsdma_job = hsdma_running_job;
++	hsdma_running_job = NULL;
++	list_add_tail(&hsdma_job->lh, &hsdma_done_q);
++	hsdma_done_q_len++;
++
++	if (HSDMAC_CONTROL_STATUS_REG & (0x1 << 12)) {
++		hsdma_job->done_status = HSDMAC_RESPONSE_ERR;
++	} else {
++		hsdma_job->done_status = HSDMAC_RESPONSE_OK;
++	}
++
++	HAL_HSDMAC_DISABLE();
++
++	hsdma_busy = 0;
++
++	schedule_work(&hsdma_done_task);
++
++	if (hsdma_xfer_q_len) {
++		schedule_work(&hsdma_xfer_task);
++	}
++
++	return IRQ_HANDLED;
++}
++
++int hsdma_init(void)
++{
++	int retval;
++
++	// enable the HSDMA clock
++	HAL_PWRMGT_ENABLE_HSDMA_CLOCK();
++
++	// disable the HSDMA(normal mode, incremental address)
++	HSDMAC_CONTROL_STATUS_REG = 0x0;
++	HSDMAC_TOT_SIZE_REG = 0x10000000;
++
++	if (hsdma_job_q_init() != 0) {
++		return -EFAULT;
++	}
++
++	spin_lock_init(&hsdma_lock);
++	INIT_LIST_HEAD(&hsdma_xfer_q);
++	INIT_LIST_HEAD(&hsdma_done_q);
++
++	// Eileen , for linux kernel 2.6.24 , 20080425
++	//retval = request_irq(INTC_HSDMAC_BIT_INDEX, &hsdma_isr, SA_INTERRUPT, "STR8100 HSDMA", &hsdma_dev);
++	retval = request_irq(INTC_HSDMAC_BIT_INDEX, &hsdma_isr, IRQF_DISABLED, "STR8100 HSDMA", &hsdma_dev);
++	if (retval) {
++		printk("%s: unable to get IRQ %d (irqval=%d).\n", "STAR HSDMA", INTC_HSDMAC_BIT_INDEX, retval);
++		return retval;
++	}
++
++	return retval;
++}
++
++// Eileen , for linux kernel 2.6.24 , 20080425
++#ifdef STR8100_HSDMA_TEST
++	static int str8100_hsdma_test(void);
++#endif
++
++static int __init str8100_hsdma_init(void)
++{
++	int retval;
++
++	printk("STR8100 HSDMA driver init\n");
++	retval = hsdma_init();
++#ifdef STR8100_HSDMA_TEST
++	if (retval == 0) {
++		// Eileen ,for linux kernel 2.6.24 , 20080425
++		//move : static int str8100_hsdma_test(void);
++		(void)str8100_hsdma_test();
++	}
++#endif
++	return retval;
++}
++
++static void __exit str8100_hsdma_exit(void)
++{
++	        return;
++}
++
++module_init(str8100_hsdma_init);
++module_exit(str8100_hsdma_exit);
++
++#ifdef STR8100_HSDMA_TEST
++#define MEMSIZE_K		128
++#define MEMSIZE			(MEMSIZE_K*1024)
++
++#define NUM_HSDMA_VEC		16
++#define NUM_BYTES_PER_VEC	4096
++
++static hsdma_xfer_t hsdma_xfer_test;
++static u8 *src;
++static u8 *dst;
++
++static void hsdma_copy_end(hsdma_xfer_t *hsdma_xfer, int err)
++{
++	int i;
++
++	printk("STR8100 HSDMA Testing end\n");
++
++	if (err) {
++		printk("STR8100 HSDMA Testing failed!!\n");
++	} else {
++		for (i = 0; i < NUM_HSDMA_VEC; i++) {
++			if (memcmp((src + i * NUM_BYTES_PER_VEC), (dst + i * NUM_BYTES_PER_VEC), NUM_BYTES_PER_VEC) == 0) {
++				printk("STR8100 HSDMA Testing success started at offset: %04d:\n", i * NUM_BYTES_PER_VEC);
++			} else {
++				int j;
++				u8 *psrc;
++				u8 *pdst;
++
++				psrc = src + i * NUM_BYTES_PER_VEC;
++				pdst = dst + i * NUM_BYTES_PER_VEC;
++
++				printk("STR8100 HSDMA Testing error started at offset: %04d\n", i * NUM_BYTES_PER_VEC);
++
++				for (j = 0; j < NUM_BYTES_PER_VEC; j++) {
++					if ((j % 16) == 0) {
++						printk("\n 0x%08x: ", (u32)(psrc + j));
++					}
++					if (((j % 16) != 0) && ((j % 4) == 0)) {
++						printk(" ");
++					}
++					printk("%02x", psrc[j]);
++				}
++				printk("\n");
++	
++				for (j = 0; j < NUM_BYTES_PER_VEC; j++) {
++					if ((j % 16) == 0) {
++						printk("\n 0x%08x: ", (u32)(pdst + j));
++					}
++					if (((j % 16) != 0) && ((j % 4) == 0)) {
++						printk(" ");
++					}
++					printk("%02x", pdst[j]);
++				}
++				printk("\n");
++			}
++		}
++	}
++
++	kfree(src);
++	kfree(dst);
++}
++
++static int str8100_hsdma_test(void)
++{
++	int i;
++
++	src = kmalloc(MEMSIZE, GFP_KERNEL);
++	if (!src) goto out;
++	dst = kmalloc(MEMSIZE, GFP_KERNEL);
++	if (!dst) {
++		kfree(src);
++		goto out;
++	}
++
++	memset(src, 0xAF, MEMSIZE);
++	memset(dst, 0x00, MEMSIZE);
++
++	hsdma_xfer_test.nr_vec = NUM_HSDMA_VEC;
++	hsdma_xfer_test.hsdma_end_io = hsdma_copy_end;
++	for (i = 0; i < NUM_HSDMA_VEC; i++) {
++		hsdma_xfer_test.vec[i].data_direction = HSDMAC_MASTER0_TO_MASTER1;
++		hsdma_xfer_test.vec[i].src_addr = (u32)(src + i * NUM_BYTES_PER_VEC);
++		hsdma_xfer_test.vec[i].dst_addr = (u32)(dst + i * NUM_BYTES_PER_VEC);
++		hsdma_xfer_test.vec[i].size = NUM_BYTES_PER_VEC;
++	}
++
++	printk("STR8100 HSDMA Testing ...\n");
++	hsdma_copy(&hsdma_xfer_test);
++
++out:
++	return 0;
++}
++
++#endif // STR8100_HSDMA_TEST
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_i2s.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_i2s.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_i2s.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_i2s.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,743 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++/*
++ * defines for each channel
++ */
++#define DMAC_CH_DISABLE                0
++#define DMAC_CH_ENABLE                 1
++
++#define DMAC_CH_DST_SEL_M0             0
++#define DMAC_CH_DST_SEL_M1             1
++
++#define DMAC_CH_SRC_SEL_M0             0
++#define DMAC_CH_SRC_SEL_M1             1
++
++#define DMAC_CH_DSTAD_CTL_INC          0
++#define DMAC_CH_DSTAD_CTL_DEC          1
++#define DMAC_CH_DSTAD_CTL_FIX          2
++
++#define DMAC_CH_SRCAD_CTL_INC          0
++#define DMAC_CH_SRCAD_CTL_DEC          1
++#define DMAC_CH_SRCAD_CTL_FIX          2
++
++#define DMAC_CH_MODE_HW_HANDSHAKE      1
++
++#define DMAC_CH_SRC_WIDTH_8_BITS       0
++#define DMAC_CH_SRC_WIDTH_16_BITS      1
++#define DMAC_CH_SRC_WIDTH_32_BITS      2
++
++#define DMAC_CH_DST_WIDTH_8_BITS       0
++#define DMAC_CH_DST_WIDTH_16_BITS      1
++#define DMAC_CH_DST_WIDTH_32_BITS      2
++
++#define DMAC_CH_ABT_TRANSFER           1
++
++#define DMAC_CH_PROT1_PRIVILEGED_MODE  1
++#define DMAC_CH_PROT1_USER_MODE        0
++
++#define DMAC_CH_PROT2_BUFFERABLE       1
++#define DMAC_CH_PROT2_NON_BUFFERABLE   0
++
++#define DMAC_CH_PROT3_CACHEABLE        1
++#define DMAC_CH_PROT3_NON_CACHEABLE    0
++
++#define DMAC_CH_PRI_LEVEL_0            0
++#define DMAC_CH_PRI_LEVEL_1            1
++#define DMAC_CH_PRI_LEVEL_2            2
++#define DMAC_CH_PRI_LEVEL_3            3
++
++#define DMAC_CH_TC_MASK_DISABLE        0
++#define DMAC_CH_TC_MASK_ENABLE         1
++
++#define DMAC_MAX_CHANNEL_NUM           (8)
++
++
++#define DMAC_CH0_ID                    (1 << 0)
++#define DMAC_CH1_ID                    (1 << 1)
++#define DMAC_CH2_ID                    (1 << 2)
++#define DMAC_CH3_ID                    (1 << 3)
++#define DMAC_CH4_ID                    (1 << 4)
++#define DMAC_CH5_ID                    (1 << 5)
++#define DMAC_CH6_ID                    (1 << 6)
++#define DMAC_CH7_ID                    (1 << 7)
++#define DMAC_CH_ID(idx)                (1 << idx) 
++
++#define DMAC_LITTLE_ENDIAN             (0)
++#define DMAC_BIG_ENDIAN                (1)
++
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++
++#include <linux/kernel.h>	/* printk() */
++#include <linux/errno.h>	/* error codes */
++#include <linux/types.h>	/* size_t */
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++#include <linux/pci.h>
++
++#include <asm/system.h>		/* cli(), *_flags */
++#include <asm/uaccess.h>	/* copy_*_user */
++
++#include <mach/star_powermgt.h>
++#include <mach/star_misc.h>
++#include <mach/star_i2s.h>
++#include <mach/star_dmac.h>
++
++MODULE_AUTHOR("Mac Lin");
++MODULE_LICENSE("Dual BSD/GPL");
++
++
++#define CONFIG_I2S_USE_DMA
++//Debug = left only
++#define DEBUG	
++
++static struct proc_dir_entry *star_i2s_proc_entry=NULL;
++static u32 sampling_rate=32000;
++static u32 sample_size=16;
++
++#define DMA_TRANSFER_MAX_BYTE    (0xfff<<(sample_size>>4)) 
++#define BUFSIZE (0xfff<<4) //twice the 32-bit DMA transfer byte size
++
++static u8* lbuffer;
++static u8* lbuffer_p;
++static u32 llen=0;
++static u32 lpos=0;
++static u32 i2s_err_lur=0;
++
++static u32 debug=0;
++#define DEBUG_PRINT(arg...) if(debug) printk(arg);
++
++//=================================================================================
++//
++#ifdef CONFIG_I2S_USE_DMA
++typedef struct _DMAC_HARDWARE_HANDSHAKE_OBJ_    DMAC_HARDWARE_HANDSHAKE_OBJ_T;
++
++struct _DMAC_HARDWARE_HANDSHAKE_OBJ_
++{
++    unsigned int    src_addr;                     //Src address
++    unsigned int    dst_addr;                     //Dst address
++    unsigned int    src_master;                   //0:AHB0, 1:AHB1
++    unsigned int    dst_master;                   //0:AHB0, 1:AHB1
++    unsigned int    dstad_ctl;                    //0:Incr, 1:Decr, 2:Fix
++    unsigned int    srcad_ctl;                    //0:Incr, 1:Decr, 2:Fix
++    unsigned int    src_width;                    //0:8bits, 1:16bits, 2:32bits
++    unsigned int    dst_width;                    //0:8bits, 1:16bits, 2:32bits
++    unsigned int    transfer_bytes;               //Byte Count to be transferred
++    unsigned int    channel_id;                   //0~7 for Channel0-7 selection
++    unsigned int    channel_num;                   //0~7
++    unsigned int    target_select;                //target ID
++    unsigned int    src_burst_size;               //number of transfer 
++}; 
++
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8759_dma_handshake_left_tx;
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8759_dma_handshake_right_tx;
++
++static u32                          i2s_wm8759_dma_right_tx_channel = 1;
++
++
++
++
++void Hal_Dmac_Configure_DMA_Handshake(DMAC_HARDWARE_HANDSHAKE_OBJ_T *dmac_obj)
++{
++    u32    channel_control,interrupt_mask_config,ch;
++
++    
++    /*
++     * Configure DMA controller for UART's hardware DMA handshake mode
++     */    
++    HAL_DMAC_DISABLE();
++    
++//#if (ENDIAN_MODE == BIG_ENDIAN)
++#if 0
++    /*Set Master0 and Master 1 endianness as Big Endian*/
++    HAL_DMAC_SET_MASTER0_BIG_ENDIAN();
++    HAL_DMAC_SET_MASTER1_BIG_ENDIAN();
++#else
++    /*Set Master0 and Master 1 endianness as Little Endian*/
++    HAL_DMAC_SET_MASTER0_LITTLE_ENDIAN();
++    HAL_DMAC_SET_MASTER1_LITTLE_ENDIAN();
++#endif
++
++    //Clear TC interrupt status    
++    HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(0xFF);        // 8 channels
++
++    //Clear Errot/Abort interrupt status    
++    HAL_DMAC_CLEAR_ERROR_ABORT_INTERRUPT_STATUS(0x00FF00FF);    // 8 channels
++
++    /*
++     * Configure DMA's channel control
++     */   
++    channel_control = ((DMAC_CH_TC_MASK_DISABLE << 31) | \
++                       ((dmac_obj->target_select&0xf) << 25) | \
++                       (DMAC_CH_PRI_LEVEL_3 << 22) | \
++                       (DMAC_CH_PROT3_NON_CACHEABLE << 21) | \
++                       (DMAC_CH_PROT2_NON_BUFFERABLE << 20) | \
++                       (DMAC_CH_PROT1_PRIVILEGED_MODE << 19) | \
++                       ((dmac_obj->src_burst_size&0x7) << 16) | \
++                       ((dmac_obj->src_width&0x7) << 11) | \
++                       ((dmac_obj->dst_width&0x7) << 8) | \
++                       (DMAC_CH_MODE_HW_HANDSHAKE << 7) | \
++                       ((dmac_obj->srcad_ctl&0x3) << 5) | \
++                       ((dmac_obj->dstad_ctl&0x3) << 3) | \
++                       (dmac_obj->src_master << 2) | \
++                       (dmac_obj->dst_master << 1) | \
++                       (DMAC_CH_DISABLE));
++
++    for (ch = 0; ch < DMAC_MAX_CHANNEL_NUM; ch++)
++    {
++        if (dmac_obj->channel_id & DMAC_CH_ID(ch))
++        {  
++            // 1. Set CSR
++            DMAC_CH_CSR_REG(ch) = channel_control & 0xFFFFFFFE; //Disable CH(n) DMA
++                
++            // 2.1 Reset Abort/Error/Terminal Count INT 
++            DMAC_CH_CFG_REG(ch) &= ~(0x07);
++            
++            // 2.2 Disable  Abort Count INT        
++            interrupt_mask_config = (1 << 2);
++            
++            DMAC_CH_CFG_REG(ch) |= (interrupt_mask_config & 0x07);
++        }                               	
++    }
++
++    for (ch = 0; ch < DMAC_MAX_CHANNEL_NUM; ch++)
++    {
++        if (dmac_obj->channel_id & DMAC_CH_ID(ch))
++        {  
++            //Set Src address register
++            DMAC_CH_SRC_ADDR_REG(ch)= dmac_obj->src_addr;
++
++            //Set Dst address register
++            DMAC_CH_DST_ADDR_REG(ch)= dmac_obj->dst_addr;    
++
++            //Set Transfer Number
++            if (dmac_obj->src_width == DMAC_CH_SRC_WIDTH_8_BITS)
++            {
++                DMAC_CH_SIZE_REG(ch) = (dmac_obj->transfer_bytes & 0x0FFF);
++                DEBUG_PRINT("%s: 8-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,dmac_obj->transfer_bytes,ch,DMAC_CH_SIZE_REG(ch));
++            }
++            else if (dmac_obj->src_width == DMAC_CH_SRC_WIDTH_16_BITS)
++            {                                  
++                DMAC_CH_SIZE_REG(ch) = ((dmac_obj->transfer_bytes >> 1) + (dmac_obj->transfer_bytes % 2)) & 0x0FFF;
++                DEBUG_PRINT("%s: 16-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,dmac_obj->transfer_bytes,ch,DMAC_CH_SIZE_REG(ch));
++            }
++            else if (dmac_obj->src_width == DMAC_CH_SRC_WIDTH_32_BITS)
++            {
++                DMAC_CH_SIZE_REG(ch) = ((dmac_obj->transfer_bytes >> 2) + ((dmac_obj->transfer_bytes % 4) ? 1 : 0)) & 0x0FFF;
++                DEBUG_PRINT("%s: 32-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,dmac_obj->transfer_bytes,ch,DMAC_CH_SIZE_REG(ch));
++            }
++            else
++            {
++            	DEBUG_PRINT("%s: dead\n",__FUNCTION__);
++                while (1);
++            }
++
++            //Enable Channel DMA transfer 
++            HAL_DMAC_ENABLE_CHANNEL(ch);
++             
++            //Set Channel's Sync logic
++            DMAC_SYNC_REG |= (1 << ch);
++
++            //For NON Chain Transfer, clear LLP registers
++            DMAC_CH_LLP_REG(ch) = 0;
++        }
++    }
++}
++
++void I2s_WM8759_Configure_DMA_Hardware_Handshake(void)
++{
++    /*
++     * Configure DMA's channel setting for I2S's Left Channel Tx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    i2s_wm8759_dma_handshake_left_tx.channel_num = 0;
++    i2s_wm8759_dma_handshake_left_tx.channel_id = DMAC_CH_ID(i2s_wm8759_dma_handshake_left_tx.channel_num);
++    i2s_wm8759_dma_handshake_left_tx.target_select = DMAC_HW_HAND_SHAKE_I2S_TX_LEFT_ID;
++    i2s_wm8759_dma_handshake_left_tx.src_addr = (u32)lbuffer_p;
++    i2s_wm8759_dma_handshake_left_tx.src_master = DMAC_CH_SRC_SEL_M1;
++    i2s_wm8759_dma_handshake_left_tx.dst_master = DMAC_CH_DST_SEL_M0;
++    i2s_wm8759_dma_handshake_left_tx.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;
++    i2s_wm8759_dma_handshake_left_tx.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;
++    
++	switch(sample_size){
++	case 16:
++		i2s_wm8759_dma_handshake_left_tx.dst_addr = (SYSPA_I2S_BASE_ADDR + 0xCA);
++		i2s_wm8759_dma_handshake_left_tx.src_width = DMAC_CH_SRC_WIDTH_16_BITS;
++		i2s_wm8759_dma_handshake_left_tx.dst_width = DMAC_CH_DST_WIDTH_16_BITS;
++		break;
++	case 32:
++		i2s_wm8759_dma_handshake_left_tx.dst_addr = (SYSPA_I2S_BASE_ADDR + 0xC8);
++		i2s_wm8759_dma_handshake_left_tx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++		i2s_wm8759_dma_handshake_left_tx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++		break;
++	}
++
++//    i2s_wm8759_dma_handshake_left_tx.dst_width = DMAC_CH_DST_WIDTH_16_BITS;
++
++    /*
++     * Note here the total number of bytes for each DMA transfer is specified!!
++     */
++//    i2s_wm8759_dma_handshake_left_tx.transfer_bytes = DMA_TRANSFER_MAX_BYTE;
++    i2s_wm8759_dma_handshake_left_tx.transfer_bytes = (llen<DMA_TRANSFER_MAX_BYTE)?llen:DMA_TRANSFER_MAX_BYTE;
++
++    i2s_wm8759_dma_handshake_left_tx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;   
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8759_dma_handshake_left_tx);
++
++#ifndef DEBUG 
++    /*
++     * Configure DMA's channel setting for I2S's Right Channel Tx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    i2s_wm8759_dma_handshake_right_tx.channel_id = DMAC_CH_ID(i2s_wm8759_dma_right_tx_channel);
++    
++    i2s_wm8759_dma_handshake_right_tx.target_select = DMAC_HW_HAND_SHAKE_I2S_TX_RIGHT_ID;
++
++    i2s_wm8759_dma_handshake_right_tx.src_addr = (u32)rbuffer_p;
++
++    i2s_wm8759_dma_handshake_right_tx.dst_addr = (SYSPA_I2S_BASE_ADDR + 0xC4);
++
++    i2s_wm8759_dma_handshake_right_tx.src_master = DMAC_CH_SRC_SEL_M1;
++    
++    i2s_wm8759_dma_handshake_right_tx.dst_master = DMAC_CH_DST_SEL_M0;
++
++    i2s_wm8759_dma_handshake_right_tx.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;
++    
++    i2s_wm8759_dma_handshake_right_tx.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;
++
++    i2s_wm8759_dma_handshake_right_tx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    
++    i2s_wm8759_dma_handshake_right_tx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    /*
++     * Note here the total number of bytes for each DMA transfer is specified!!
++     */
++    i2s_wm8759_dma_handshake_right_tx.transfer_bytes = DMA_TRANSFER_MAX_BYTE;
++
++    i2s_wm8759_dma_handshake_right_tx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;   
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8759_dma_handshake_right_tx);
++#endif
++    return;
++}
++#endif //CONFIG_I2S_USE_DMA
++
++
++//=================================================================================
++//
++
++extern void str8100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++
++#ifdef CONFIG_I2S_USE_DMA
++static irqreturn_t str8100_dma_tc_irq_handler(int this_irq, void *dev_id /*, struct pt_regs *regs*/)
++{
++	u32 dma_tc_status,tot_size;
++	u32 len;
++//printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++
++    HAL_DMAC_READ_TERMINAL_COUNT_INTERRUPT_STATUS(dma_tc_status);
++
++    /*
++     * For DMA's Tx for I2S Left Channel
++     */
++	if (dma_tc_status & DMAC_CH_ID(i2s_wm8759_dma_handshake_left_tx.channel_num))
++	{                      
++		HAL_DMAC_DISABLE_CHANNEL(i2s_wm8759_dma_handshake_left_tx.channel_num);
++		HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8759_dma_handshake_left_tx.channel_num));
++		lpos+=i2s_wm8759_dma_handshake_left_tx.transfer_bytes;
++		if(lpos<llen){
++			/*
++			 * Re-initialize DMA's channel for Left_Tx
++			 */
++			DMAC_CH_SRC_ADDR_REG(i2s_wm8759_dma_handshake_left_tx.channel_num) = (u32)lbuffer_p+lpos;
++			DMAC_CH_DST_ADDR_REG(i2s_wm8759_dma_handshake_left_tx.channel_num) = (SYSPA_I2S_BASE_ADDR + 0xC8);        
++			
++			/*
++			 * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
++			 * number of source transfer width!
++			 */        
++			len=(llen - lpos);
++			i2s_wm8759_dma_handshake_left_tx.transfer_bytes= (len<DMA_TRANSFER_MAX_BYTE)?len:DMA_TRANSFER_MAX_BYTE;
++
++			if (i2s_wm8759_dma_handshake_left_tx.src_width == DMAC_CH_SRC_WIDTH_16_BITS)
++			{
++			    tot_size = (i2s_wm8759_dma_handshake_left_tx.transfer_bytes >> 1) + ((i2s_wm8759_dma_handshake_left_tx.transfer_bytes % 2) ? 1 : 0);
++			}
++			else if (i2s_wm8759_dma_handshake_left_tx.src_width == DMAC_CH_SRC_WIDTH_32_BITS)
++			{
++			    tot_size = (i2s_wm8759_dma_handshake_left_tx.transfer_bytes >> 2) + ((i2s_wm8759_dma_handshake_left_tx.transfer_bytes % 4) ? 1 : 0);
++			}
++			else
++			{
++			    tot_size = i2s_wm8759_dma_handshake_left_tx.transfer_bytes;
++			}
++			
++			DMAC_CH_SIZE_REG(i2s_wm8759_dma_handshake_left_tx.channel_num) = tot_size & 0x0FFF;
++			HAL_DMAC_ENABLE_CHANNEL(i2s_wm8759_dma_handshake_left_tx.channel_num);
++//printk("%s: 32-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,i2s_wm8759_dma_handshake_left_tx.transfer_bytes,i2s_wm8759_dma_handshake_left_tx.channel_num,DMAC_CH_SIZE_REG(i2s_wm8759_dma_handshake_left_tx.channel_num));
++
++	}else{
++		llen=lpos=0;
++	}
++	}
++
++
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++static irqreturn_t str8100_dma_err_irq_handler(int this_irq, void *dev_id /*, struct pt_regs *regs*/)
++{
++	u32 dma_error_status,dma_ch;
++printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++
++	HAL_DMAC_READ_ERROR_ABORT_INTERRUPT_STATUS(dma_error_status);
++	for (dma_ch = 0; dma_ch < DMAC_MAX_CHANNEL_NUM; dma_ch++)
++	{
++		if (dma_error_status & DMAC_CH_ID(dma_ch))
++		{
++			printk("%s: this_irq=%d, DMA channel error on ch %d\n",__FUNCTION__,this_irq,dma_ch);
++			HAL_DMAC_DISABLE_CHANNEL(dma_ch);
++			HAL_DMAC_CLEAR_ERROR_ABORT_INTERRUPT_STATUS(DMAC_CH_ID(dma_ch));
++		}
++	}	
++	
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++	return IRQ_HANDLED;
++}
++#endif //CONFIG_I2S_USE_DMA
++
++static irqreturn_t str8100_i2s_irq_handler(int this_irq, void *dev_id /*, struct pt_regs *regs*/)
++{
++	u32 interrupt_status;
++	DEBUG_PRINT("%s: this_irq=%d, I2S_INTERRUPT_STATUS_REG=0x%.8x,llen=%d,lpos=%d\n",__FUNCTION__,this_irq,I2S_INTERRUPT_STATUS_REG,llen,lpos);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++	interrupt_status = I2S_INTERRUPT_STATUS_REG;   
++if((llen<lpos)||llen==0)     HAL_I2S_DISABLE_I2S();
++
++#ifndef CONFIG_I2S_USE_DMA
++		I2S_RIGHT_TRANSMIT_DATA_REG=0;
++
++	if ((lpos<=llen) && (interrupt_status & I2S_TXBF_L_EMPTY_FLAG)){
++		switch(sample_size){
++			case 16:
++				I2S_LEFT_TRANSMIT_DATA_REG=(*((u16*)(&lbuffer[lpos])))<<16;lpos+=2;
++				break;
++			case 32:
++				I2S_LEFT_TRANSMIT_DATA_REG=*((u32*)(&lbuffer[lpos]));lpos+=4;
++				break;
++		}
++		
++		if(lpos>llen){
++			// Disable Left Channel's Transmit Buffer Interrupt Sources
++			I2S_INTERRUPT_ENABLE_REG &= ~(I2S_TXBF_L_EMPTY_FLAG | I2S_TXBF_L_UR_FLAG);
++			lpos=llen=0;
++		}
++	}
++#endif //!CONFIG_I2S_USE_DMA
++
++
++	if (llen>=lpos && (interrupt_status & I2S_TXBF_L_UR_FLAG)){
++		// Clear I2S interrupt status
++		i2s_err_lur++;
++		if(i2s_err_lur>10)
++			I2S_INTERRUPT_ENABLE_REG &= ~(I2S_TXBF_L_UR_FLAG);
++//			HAL_I2S_DISABLE_I2S();
++		
++		printk("%s: Left Channel Tx Underrun!,llen=%d, lpos=%d, interrupt_status=%.8x,i2s_err_lur=%d\n",__FUNCTION__,llen,lpos,interrupt_status,i2s_err_lur);
++	}
++	I2S_INTERRUPT_STATUS_REG &= 0xf0;
++
++	
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++static int str8100_i2s_init(void){
++	DEBUG_PRINT("%s: \n",__FUNCTION__);
++	int ret;
++	u32 tmp;
++	
++
++	/*
++	 * Select I2S clock source; here we use 48K sampling rate for the target file.
++	 */
++	 
++	switch(sampling_rate){
++	case 48000: 
++		HAL_PWRMGT_I2S_CLOCK_SOURCE_12288000HZ(); 
++		break; 
++	case 44100:
++		HAL_PWRMGT_I2S_CLOCK_SOURCE_11289600HZ(); 
++		break;
++	case 32000: 
++		HAL_PWRMGT_I2S_CLOCK_SOURCE_8192000HZ(); 
++		break; 
++	}
++	HAL_PWRMGT_CONFIGURE_CLOCK_OUT_PIN(11,0);
++	
++	// Enable I2S pins
++	HAL_MISC_ENABLE_I2S_PINS();
++	
++	// Enable I2S clock
++	HAL_PWRMGT_ENABLE_I2S_CLOCK(); 
++
++	//Hal_Pwrmgt_Software_Reset(PWRMGT_P2S_SOFTWARE_RESET_BIT_INDEX);
++
++    /*
++     * Configure I2S to be Master & Transmitter
++     * Note the I2S's WS Clock is derived from Clock & Power Management Functional
++     * Block!!
++     */
++	I2S_CONFIGURATION_REG = /*(I2S_DATA_16_BIT << 0) |*/
++												(I2S_DATA_32_BIT << 0) |
++                        (0x0 << 4) |
++                        (0x0 << 12) |   /* Disable loopback */
++                        (0x0 << 15) |   /* Disable clock phase invert */
++                        (0x0 << 24) |   /* Disable I2S data swap */
++                        (I2S_CLOCK_256S_MODE << 25) |
++                        (I2S_I2S_MODE << 26) |
++                        (0x0 << 29) |   /* Enable I2S Transmitter */
++												(I2S_MASTER_MODE << 30) |
++												(0x0 << 31);	/* Disable I2S */
++
++	//Enable none while initializing
++	I2S_INTERRUPT_ENABLE_REG = 0x0;
++//	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG | I2S_TXBF_R_EMPTY_FLAG | I2S_TXBF_L_EMPTY_FLAG);
++
++    // Clear spurious interrupt sources
++    I2S_INTERRUPT_STATUS_REG = 0xF0;
++
++    tmp = I2S_LEFT_RECEIVE_DATA_REG;
++    tmp = I2S_RIGHT_RECEIVE_DATA_REG;
++
++    // Disable I2S
++    HAL_I2S_DISABLE_I2S();
++
++	return 0;
++}
++
++
++//=================================================================================
++static int proc_read_i2s(char *buf, char **start, off_t offset,
++                   int count, int *eof, void *data)
++{
++	int len=0;
++	DEBUG_PRINT("%s:\n",__FUNCTION__);
++	len += sprintf(buf,	"sampling_rate=%d\n"
++				"sample_size=%d\n"
++			,sampling_rate,sample_size); 
++	*eof = 1;
++	return len;
++}
++
++static proc_write_i2s(struct file *file, const char *buffer, unsigned long count, void *data){
++	int len=0;
++	DEBUG_PRINT("%s: sample size %d, sampling rate %d, count=%d\n",__FUNCTION__,sample_size,sampling_rate,count);
++	
++	//is buffer free?
++	if(lpos!=llen){
++		printk("%s: buffer not free\n");
++		return -EBUSY;
++	}
++	if(sampling_rate!=32000&&sampling_rate!=44100&&sampling_rate!=48000){
++		printk("%s: invalid sampling rate(%d)\n",sampling_rate);
++		return -EFAULT;
++	}
++	if(sample_size!=16&&sample_size!=32){
++		printk("%s: invalid sample size(%d)\n",sample_size);
++		return -EFAULT;
++	}
++
++	//copy the raw data to local buffer	
++	if(count>BUFSIZE) len=BUFSIZE;
++	else len=count;
++	
++	if(copy_from_user(lbuffer,buffer,len)){
++		return -EFAULT;	
++	}
++	llen=len;
++	lpos=0;
++	i2s_err_lur=0;
++	
++	str8100_i2s_init();
++
++#ifdef CONFIG_I2S_USE_DMA
++    /*
++     * Configure DMA for hardware handshake for I2S
++     * Note the DMA is NOT enabled after invoking the following function, but the specified
++     * DMA channels are enabled!!
++     */
++    i2s_wm8759_dma_right_tx_channel = 1;   
++
++    I2s_WM8759_Configure_DMA_Hardware_Handshake();  
++
++#endif //CONFIG_I2S_USE_DMA
++	//fill the tx left/right registers
++
++		switch(sample_size){
++			case 16:
++				I2S_LEFT_TRANSMIT_DATA_REG=(*((u16*)(&lbuffer[lpos])))<<16;lpos+=2;
++				break;
++			case 32:
++				I2S_LEFT_TRANSMIT_DATA_REG=*((u32*)(&lbuffer[lpos]));lpos+=4;
++				break;
++		}
++
++	I2S_RIGHT_TRANSMIT_DATA_REG=0;
++
++#ifdef CONFIG_I2S_USE_DMA
++	/*
++	 * Enable I2S's interrupt sources
++	 * Note for DMA hardware handshake, we only need to enable Left/Right Channel's 
++	 * Transmit Buffer Underrun.
++	 */
++#ifdef DEBUG	
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_L_UR_FLAG);
++#else
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG);
++#endif
++#else //CONFIG_I2S_USE_DMA
++#ifdef DEBUG	
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_L_UR_FLAG | I2S_TXBF_L_EMPTY_FLAG);
++#else
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG | I2S_TXBF_R_EMPTY_FLAG | I2S_TXBF_L_EMPTY_FLAG);
++#endif
++#endif //CONFIG_I2S_USE_DMA
++
++	// Enable CPU interrupt
++	local_irq_enable();
++	
++#ifdef CONFIG_I2S_USE_DMA
++	/*
++	 * Note DMA must be enabled first before I2S is enabled
++	 */
++	HAL_DMAC_ENABLE();
++#endif //CONFIG_I2S_USE_DMA
++	HAL_I2S_ENABLE_I2S();
++
++
++	while (1){
++		local_irq_disable();
++		if (lpos>llen||llen==0){
++			// Disable I2S
++			HAL_I2S_DISABLE_I2S();
++			break;
++		}
++		local_irq_enable();
++	}
++	DEBUG_PRINT("%s: exit. i2s_err_lur=%d\n",__FUNCTION__,i2s_err_lur);
++
++	local_irq_enable();
++
++	return len;
++
++debug:
++	HAL_I2S_DISABLE_I2S();
++	return count;
++}
++
++static void __devexit i2s_exit_module(void)
++{
++	printk("%s:\n",__FUNCTION__);
++	remove_proc_entry("str8100/i2s", NULL);
++	free_irq(INTC_I2S_BIT_INDEX, NULL);
++#ifdef CONFIG_I2S_USE_DMA
++	free_irq(INTC_GDMAC_TC_BIT_INDEX, NULL);
++	free_irq(INTC_GDMAC_ERROR_BIT_INDEX, NULL);
++#endif //CONFIG_I2S_USE_DMA
++	if(lbuffer) {
++		pci_free_consistent(NULL, BUFSIZE, lbuffer, lbuffer_p);
++		lbuffer=lbuffer_p=NULL;
++	}
++}
++
++static int __devinit i2s_init_module(void)
++{
++	u32 ret;
++	
++	printk("%s:\n",__FUNCTION__);
++#ifdef CONFIG_I2S_USE_DMA
++	printk("%s: DMA Enabled...\n",__FUNCTION__);
++#endif //CONFIG_I2S_USE_DMA
++
++	star_i2s_proc_entry = create_proc_entry("str8100/i2s", S_IFREG | S_IRUGO, NULL);
++	if(!star_i2s_proc_entry){
++		return -EBUSY;
++	}
++	star_i2s_proc_entry->read_proc=proc_read_i2s;
++	star_i2s_proc_entry->write_proc=proc_write_i2s;
++	
++	lbuffer = pci_alloc_consistent(NULL, BUFSIZE, &lbuffer_p);
++	if(!lbuffer){
++		printk("%s: alloc lbuffer failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++
++	str8100_set_interrupt_trigger (INTC_I2S_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_LOW);
++	if ((ret=request_irq(INTC_I2S_BIT_INDEX, str8100_i2s_irq_handler, 0, "i2s", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_I2S_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++
++#ifdef CONFIG_I2S_USE_DMA
++	str8100_set_interrupt_trigger (INTC_GDMAC_TC_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_TC_BIT_INDEX, str8100_dma_tc_irq_handler, 0, "dma tc", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_TC_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++	str8100_set_interrupt_trigger (INTC_GDMAC_ERROR_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_ERROR_BIT_INDEX, str8100_dma_err_irq_handler, 0, "dma error", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_ERROR_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++#endif //CONFIG_I2S_USE_DMA
++
++	return 0;
++exit1:
++	i2s_exit_module();
++	return -EBUSY;
++}
++
++module_init(i2s_init_module);
++module_exit(i2s_exit_module);
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_intc.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_intc.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_intc.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_intc.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,222 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++
++#include <mach/hardware.h>
++#include <asm/mach/irq.h>
++#include <asm/irq.h>
++
++#define INTC_TRIGGER_UNKNOWN -1
++
++typedef struct
++{
++	int	mode;
++	int	level;
++} intc_trigger_t;
++
++static intc_trigger_t intc_trigger_table[] =
++{
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 0
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 1
++	{ INTC_EDGE_TRIGGER,	INTC_FALLING_EDGE	},	// 2
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 3
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 4
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 5
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 6
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 7
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 8
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 9
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 10
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 11
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 12
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 13
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 14
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 15
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 16
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 17
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 18
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 19
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 20
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 21
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 22
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 23
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 24
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 25
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 26
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 27
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 28
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 29
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 30
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 31
++};
++
++static u32 intc_edge_trigger_bitmap;
++
++/*
++ * Configure interrupt trigger mode to be level trigger or edge trigger
++ */
++static inline void str8100_set_irq_mode(unsigned int irq, unsigned int mode)
++{
++	volatile unsigned int val;
++
++	if (irq < 0 || irq > NR_IRQS) {
++		return;
++	}
++
++	if ((mode != INTC_LEVEL_TRIGGER) &&
++		(mode != INTC_EDGE_TRIGGER)) {
++		return;
++	}
++
++	val = INTC_INTERRUPT_TRIGGER_MODE_REG;
++
++	if (mode == INTC_LEVEL_TRIGGER) {
++		if (val & (1UL << irq)) {
++			val &= ~(1UL << irq);
++			INTC_INTERRUPT_TRIGGER_MODE_REG = val;
++		}
++	} else {
++		intc_edge_trigger_bitmap |= (1UL << irq);
++		if (!(val & (1UL << irq))) {
++			val |= (1UL << irq);
++			INTC_INTERRUPT_TRIGGER_MODE_REG = val;
++		}
++	}
++}	
++
++/*
++ * Configure interrupt trigger level to be Active High/Low or Rising/Falling Edge
++ */
++static inline void str8100_set_irq_level(unsigned int irq, unsigned int level)
++{
++	volatile unsigned int val;
++
++	if (irq < 0 || irq > NR_IRQS) {
++		return;
++	}
++
++	if ((level != INTC_ACTIVE_HIGH) &&
++		(level != INTC_ACTIVE_LOW) &&
++		(level != INTC_RISING_EDGE) &&
++		(level != INTC_FALLING_EDGE)) {
++		return;
++	}
++
++	val = INTC_INTERRUPT_TRIGGER_LEVEL_REG;
++
++	if ((level == INTC_ACTIVE_HIGH) ||
++		(level == INTC_RISING_EDGE)) {
++		if (val & (1UL << irq)) {
++			val &= ~(1UL << irq);
++			INTC_INTERRUPT_TRIGGER_LEVEL_REG = val;
++		}
++	} else {
++		if (!(val & (1UL << irq))) {
++			val |= (1UL << irq);
++			INTC_INTERRUPT_TRIGGER_LEVEL_REG = val;
++		}
++	}
++}
++
++/*
++ * Configure interrupt trigger mode and trigger level
++ */
++void str8100_set_interrupt_trigger(unsigned int irq, unsigned int mode, unsigned int level)
++{
++	str8100_set_irq_mode(irq, mode);
++	str8100_set_irq_level(irq, level);
++}
++EXPORT_SYMBOL(str8100_set_interrupt_trigger);
++
++/*
++ * Mask/Disable this interrupt source
++ */
++void str8100_mask_irq(unsigned int irq)
++{
++      
++//	if (irq != INTC_NIC_RXRC_BIT_INDEX && irq != INTC_NIC_RXQF_BIT_INDEX) {
++		// Mask/Disable this interrupt source
++		INTC_INTERRUPT_MASK_REG = (1UL << irq);
++//	}
++}
++
++/*
++ * Un-Mask/Enable this interrupt source
++ */
++void str8100_unmask_irq(unsigned int irq)
++{
++         
++#ifndef CONFIG_VIC_INTERRUPT
++	// Clear interrupt status of the interrupt source which is edge-triggered
++	INTC_EDGE_INTERRUPT_SOURCE_CLEAR_REG = (1UL << irq);
++#endif
++	// Enable this interrupt source
++	INTC_INTERRUPT_MASK_CLEAR_REG = (1UL << irq);
++}
++
++static struct irq_chip str8100_irqchip = {
++	.ack	= str8100_mask_irq,
++	.mask	= str8100_mask_irq,
++	.unmask	= str8100_unmask_irq,
++};
++
++void __init str8100_init_irq(void)
++{
++	int i;
++
++   //printk("str8100_init_irq()\n");
++      
++   disable_hlt();
++   
++	INTC_INTERRUPT_MASK_REG = 0xFFFFFFFF;
++	INTC_EDGE_INTERRUPT_SOURCE_CLEAR_REG = 0xFFFFFFFF;
++	INTC_SOFTWARE_INTERRUPT_CLEAR_REG = 0xFFFFFFFF;
++	INTC_SOFTWARE_PRIORITY_MASK_REG = 0x0;
++	INTC_FIQ_SELECT_REG = 0x0;
++#ifdef CONFIG_VIC_INTERRUPT
++	for (i = 0; i < NR_IRQS; i++) {
++		(*((u32 volatile *)(SYSVA_VIC_BASE_ADDR + 0x40 + (i << 2)))) = i;
++	}
++	INTC_VECTOR_INTERRUPT_ENABLE_REG = 1;
++#else
++	INTC_VECTOR_INTERRUPT_ENABLE_REG = 0;
++#endif
++
++	for (i = 0; i < NR_IRQS; i++) {
++		if (intc_trigger_table[i].mode != INTC_TRIGGER_UNKNOWN) {
++			str8100_set_irq_mode(i, intc_trigger_table[i].mode);
++			str8100_set_irq_level(i, intc_trigger_table[i].level);
++		}
++	}
++	
++	for (i = 0; i < NR_IRQS;  i++) {
++		set_irq_chip(i, &str8100_irqchip);
++		/* scott.patch */
++		set_irq_handler(i, handle_level_irq);
++		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
++	}
++}
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_misc.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_misc.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_misc.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_misc.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,210 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++//#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/proc_fs.h>
++#include <asm/mach/map.h>
++#include <mach/hardware.h>
++
++static struct map_desc str8100_map_desc[64];
++static int str8100_map_desc_count;
++
++#define REG_DEBUG_CMD_BUFFER_SIZE	128
++#define REG_DEBUG_RESULT_BUFFER_SIZE	256
++
++struct proc_dir_entry *str8100_proc_dir;
++EXPORT_SYMBOL(str8100_proc_dir);
++static struct proc_dir_entry *star_reg_debug_proc_entry;
++static char str8100_reg_debug_cmd_buf[REG_DEBUG_CMD_BUFFER_SIZE];
++static char str8100_reg_debug_result_buf[REG_DEBUG_RESULT_BUFFER_SIZE];
++
++void str8100_register_map_desc(struct map_desc *map, int count)
++{
++	if (count) {
++		if (str8100_map_desc) {
++			int i;
++			for (i = 0; i < count; i++) {
++				str8100_map_desc[i].virtual = map->virtual;
++				str8100_map_desc[i].pfn = map->pfn;
++				str8100_map_desc[i].length = map->length;
++				str8100_map_desc[i].type = map->type;
++				map++;
++			}
++			str8100_map_desc_count = count;
++		}
++	}
++}
++
++u32 str8100_query_map_desc_by_phy(u32 addr)
++{
++	struct map_desc *map;
++	int i;
++	u32 ret_addr = 0;
++	for (i = 0; i < str8100_map_desc_count; i++) {
++		map = &str8100_map_desc[i];
++		if (addr >= (map->pfn << PAGE_SHIFT) && addr < ((map->pfn << PAGE_SHIFT) + map->length)) {
++			ret_addr = map->virtual + (addr - (map->pfn << PAGE_SHIFT));
++			break;
++		}
++	}
++
++	return ret_addr;
++}
++
++u32 str8100_query_map_desc_by_vir(u32 addr)
++{
++	struct map_desc *map;
++	int i;
++	u32 ret_addr = 0;
++	for (i = 0; i < str8100_map_desc_count; i++) {
++		map = &str8100_map_desc[i];
++		if (addr >= map->virtual && addr < (map->virtual + map->length)) {
++			ret_addr = (map->pfn << PAGE_SHIFT) + (addr - map->virtual);
++			break;
++		}
++	}
++
++	return ret_addr;
++}
++
++static int star_reg_debug_read_proc(char *buffer, char **start, off_t offset,
++	int length, int *eof, void *data)
++{
++	int count;
++	int num = 0;
++
++	if (str8100_reg_debug_cmd_buf[0]) {
++		count = strlen(str8100_reg_debug_cmd_buf);
++		sprintf(buffer, str8100_reg_debug_cmd_buf, count);
++		num += count;
++	}
++	if (str8100_reg_debug_result_buf[0]) {
++		count = strlen(str8100_reg_debug_result_buf);
++		sprintf(buffer + num, str8100_reg_debug_result_buf, count);
++		num += count;
++	}
++
++	return num;
++}
++
++static int
++star_reg_debug_write_proc(struct file *file, const char __user *buffer,
++	unsigned long count, void *data)
++{
++	char *str;
++	char *cmd;
++
++	if (count > 0) {
++		str = (char *)buffer,
++		cmd = strsep(&str, "\t \n");
++		if (!cmd) goto err_out;
++		if (strcmp(cmd, "dump") == 0) {
++			u32 addr;
++			u32 vir_addr;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 16);
++			if (addr & 0x3) goto err_out;
++			vir_addr = str8100_query_map_desc_by_phy(addr);
++			sprintf(str8100_reg_debug_cmd_buf,
++				"dump 0x%08x\n",
++				addr);
++			if (!vir_addr) goto err_out;
++			sprintf(str8100_reg_debug_result_buf,
++				"physical addr: 0x%08x content: 0x%08x\n",
++				addr,
++				*(volatile unsigned int __force *)(vir_addr));
++		} else if (strcmp(cmd, "write") == 0) {
++			u32 addr;
++			u32 vir_addr;
++			u32 data;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 16);
++			arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			data = simple_strtoul(arg, &arg, 16);
++			if (addr & 0x3) goto err_out;
++			vir_addr = str8100_query_map_desc_by_phy(addr);
++			if (!vir_addr) goto err_out;
++			*(volatile unsigned int __force *)(vir_addr) = data;
++			sprintf(str8100_reg_debug_cmd_buf,
++				"write 0x%08x 0x%08x\n",
++				addr, data);
++			sprintf(str8100_reg_debug_result_buf,
++				"physical addr: 0x%08x content: 0x%08x\n",
++				addr,
++				*(volatile unsigned int __force *)(vir_addr));
++		} else {
++			goto err_out;
++		}
++	}
++
++	return count;
++
++err_out:
++	return -EFAULT;
++}
++
++static int __init star_reg_debug_proc_init(void)
++{
++	star_reg_debug_proc_entry = create_proc_entry("str8100/reg_debug", S_IFREG | S_IRUGO, NULL);
++	if (star_reg_debug_proc_entry) {
++		star_reg_debug_proc_entry->read_proc = star_reg_debug_read_proc;
++		star_reg_debug_proc_entry->write_proc = star_reg_debug_write_proc;
++	}
++
++	return 0;
++}
++
++static int __init str8100_proc_dir_create(void)
++{
++	str8100_proc_dir = proc_mkdir("str8100", NULL);
++	if (!str8100_proc_dir) {
++		printk("Error: cannot create str8100 proc dir entry at /proc/str8100\n");
++		return -EINVAL;
++	}
++
++	if (str8100_map_desc_count) {
++		(void)star_reg_debug_proc_init();
++	}
++
++	return 0;
++}
++
++extern int __init str8100_counter_setup(void);
++static int __init str8100_misc_init(void)
++{
++	str8100_proc_dir_create();
++	str8100_counter_setup();
++	return 0;
++}
++
++module_init(str8100_misc_init);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Star Semi Corporation");
++MODULE_DESCRIPTION("STR8100 MISC");
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_pci.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_pci.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_pci.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_pci.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,337 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++//#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/ptrace.h>
++#include <linux/slab.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/init.h>
++
++#include <mach/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++#include <asm/mach/pci.h>
++
++#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | ((bus) << 16) | ((device_fn) << 8) | ((where) & ~3))
++
++static struct pci_dev *pci_bridge = NULL;
++static u32 pci_config_addr;				// PCI configuration register address port
++static u32 pci_config_data;				// PCI configuration register data port
++u32 str8100_pci_irqs[4] = {0, INTC_PCI_INTA_BIT_INDEX, INTC_PCI_INTB_BIT_INDEX, 0};
++
++static int str8100_pci_read_config(struct pci_bus *bus,
++	unsigned int devfn, int where, int size, u32 *val)
++{
++	u32 v = 0;
++	u32 shift;
++	unsigned long flags;
++
++	switch (size) {
++	case 1:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		local_irq_restore(flags);
++		v = (v >> shift) & 0xff;
++		break;
++
++	case 2:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		local_irq_restore(flags);
++		v = (v >> shift) & 0xffff;
++
++		break;
++
++	case 4:
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		local_irq_restore(flags);
++		break;
++	}
++
++	*val = v;
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static int str8100_pci_write_config(struct pci_bus *bus,
++	unsigned int devfn, int where, int size, u32 val)
++{
++	u32 v;
++	u32 shift;
++	unsigned long flags;
++
++	switch (size) {
++	case 1:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		v = (v & ~(0xff << shift)) | (val << shift);
++		__raw_writel(v, pci_config_data);
++		local_irq_restore(flags);
++		break;
++
++	case 2:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		v = (v & ~(0xffff << shift)) | (val << shift);
++		__raw_writel(v, pci_config_data);
++		local_irq_restore(flags);
++		break;
++
++	case 4:
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		__raw_writel(val, pci_config_data);
++		local_irq_restore(flags);
++		break;
++	}
++
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops str8100_pci_ops = {
++	.read	= str8100_pci_read_config,
++	.write	= str8100_pci_write_config,
++};
++
++static struct resource str8100_pci_io = {
++	.name	= "PCI I/O space",
++	.start	= PCI_IO_SPACE_START,
++	.end	= PCI_IO_SPACE_END, //albert : 20040714
++	.flags	= IORESOURCE_IO,
++};
++
++static struct resource str8100_pci_nprefetch_mem = {
++	.name	= "PCI non-prefetchable",
++	.start	= PCI_NPREFETCH_MEMORY_SPACE_START,
++	.end	= PCI_NPREFETCH_MEMORY_SPACE_END,
++	.flags	= IORESOURCE_MEM,
++};
++
++static struct resource str8100_pci_prefetch_mem = {
++	.name	= "PCI prefetchable",
++	.start	= PCI_PREFETCH_MEMORY_SPACE_START,
++	.end	= PCI_PREFETCH_MEMORY_SPACE_END,
++	.flags	= IORESOURCE_MEM | IORESOURCE_PREFETCH,
++};
++
++static int __init str8100_pci_setup_resources(struct resource **resource)
++{
++	int ret = -1;
++
++	ret = request_resource(&iomem_resource, &str8100_pci_io);
++	if (ret) {
++		printk(KERN_ERR "PCI: unable to allocate I/O "
++		       "memory region (%d)\n", ret);
++		goto out;
++	}
++	ret = request_resource(&iomem_resource, &str8100_pci_nprefetch_mem);
++	if (ret) {
++		printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
++		       "memory region (%d)\n", ret);
++		goto release_io;
++	}
++	ret = request_resource(&iomem_resource, &str8100_pci_prefetch_mem);
++	if (ret) {
++		printk(KERN_ERR "PCI: unable to allocate prefetchable "
++		       "memory region (%d)\n", ret);
++		goto release_nprefetch_mem;
++	}
++
++	/*
++	 * bus->resource[0] is the IO resource for this bus
++	 * bus->resource[1] is the mem resource for this bus
++	 * bus->resource[2] is the prefetch mem resource for this bus
++	 */
++	resource[0] = &str8100_pci_io;
++	resource[1] = &str8100_pci_nprefetch_mem;
++	resource[2] = &str8100_pci_prefetch_mem;
++
++	ret = 0;
++
++	goto out;
++
++release_nprefetch_mem:
++	release_resource(&str8100_pci_nprefetch_mem);
++release_io:
++	release_resource(&str8100_pci_io);
++out:
++	return ret;
++}
++
++static irqreturn_t PCI_AHB2PCIB_ISR(int irq, void *dev_id /*, struct pt_regs * regs*/)
++{
++	u32 status;
++
++	//disable_irq(INTC_PCI_AHB2BRIDGE_BIT_INDEX);
++	pci_read_config_dword(pci_bridge, PCI_COMMAND, &status);
++	printk("AHB to bridge interrupt status: 0x%x\n", status);
++	pci_write_config_dword(pci_bridge, PCI_COMMAND, status);
++	//enable_irq(INTC_PCI_AHB2BRIDGE_BIT_INDEX);
++
++	return IRQ_HANDLED;
++}
++
++static irqreturn_t PCI_BROKEN_ISR(int irq, void *dev_id /*, struct pt_regs *regs*/)
++{
++	u32 status;
++
++	status = MISC_PCI_BROKEN_STATUS_REG & 0x1f;
++	printk("PCI BROKEN interrupt status: 0x%x\n", status);
++	MISC_PCI_BROKEN_STATUS_REG = status;
++
++	return IRQ_HANDLED;
++}
++
++int __init str8100_pci_setup(int nr, struct pci_sys_data *sys)
++{
++	if (nr != 0) {
++		return 0;
++	}
++
++	if (str8100_pci_setup_resources(sys->resource)) {
++		BUG();
++	}
++
++	return 1;
++}
++
++struct pci_bus * __devinit str8100_pci_scan_bus(int nr, struct pci_sys_data *sys)
++{
++	return pci_scan_bus(sys->busnr, &str8100_pci_ops, sys);
++}
++
++void __init str8100_pci_preinit(void)
++{
++	pci_config_addr = SYSVA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR + PCI_BRIDGE_CONFIG_ADDR_REG_OFFSET;
++	pci_config_data = SYSVA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR + PCI_BRIDGE_CONFIG_DATA_REG_OFFSET;
++
++	HAL_MISC_ENABLE_PCI_PINS();
++
++#ifdef  CONFIG_STR8100_PCI66M
++	printk("PCI clock at 66M\n");
++	HAL_PWRMGT_ENABLE_PCI_BRIDGE_66M_CLOCK();
++#else
++	printk("PCI clock at 33M\n");
++	HAL_PWRMGT_ENABLE_PCI_BRIDGE_33M_CLOCK();
++#endif
++}
++
++void __init str8100_pci_postinit(void)
++{
++//	pci_bridge = pci_find_device(PCIB_VENDOR_ID, PCIB_DEVICE_ID, NULL);
++	pci_bridge = pci_get_device(PCIB_VENDOR_ID, PCIB_DEVICE_ID, NULL);
++	if (pci_bridge == NULL) {
++		printk("PCI Bridge not found\n");
++		return;
++	} else {
++		printk("PCI Bridge found\n");
++	} 
++
++	/* scott.patch 
++	request_irq(INTC_PCI_AHB2BRIDGE_BIT_INDEX, PCI_AHB2PCIB_ISR, SA_INTERRUPT, "pci bridge", pci_bridge);
++	*/
++	request_irq(INTC_PCI_AHB2BRIDGE_BIT_INDEX, PCI_AHB2PCIB_ISR, IRQF_DISABLED, "pci bridge", (void*)pci_bridge);
++
++	MISC_PCI_CONTROL_BROKEN_MASK_REG &= ~0x1f;
++
++	/* scott.patch */
++	request_irq(INTC_PCI_BROKEN_BIT_INDEX, PCI_BROKEN_ISR, IRQF_DISABLED, "pci broken", pci_bridge);
++
++	//albert :20040803
++	pci_write_config_dword(pci_bridge, PCI_BASE_ADDRESS_0, 0x0); // = 0x0, can NOT use 0x20000000
++	pci_write_config_dword(pci_bridge, PCI_BASE_ADDRESS_1, 0x0); // = 0x0, can NOT use 0x20000000
++
++	// if we enable pci on u-boot
++	// the pci_enable_device will complain with resource collisions
++	// use this to fixup
++	{
++		int i;
++		struct resource *r;
++
++		for (i = 0; i < 6; i++) {
++			r = pci_bridge->resource + i;
++			r->start = 0;
++			r->end = 0;
++		}
++	}
++
++	pci_enable_device(pci_bridge);
++	pci_set_master(pci_bridge);
++
++	pci_write_config_byte(pci_bridge, PCI_CACHE_LINE_SIZE, 0x8); //configure cache line size
++	pci_write_config_byte(pci_bridge, PCI_LATENCY_TIMER, 0x30); //configure latency timer
++}
++
++/*
++ * map the specified device/slot/pin to an IRQ.   Different backplanes may need to modify this.
++ */
++static int __init str8100_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
++{
++	int irq;
++
++	/* slot,  pin,	irq
++	 * 0      1     0
++	 * 1      1     5
++	 * 2      1     6
++	 * 3      1     0
++	 */
++	irq = str8100_pci_irqs[((slot + pin - 1) & 3)];
++
++	printk("PCI map irq: %02x:%02x.%02x slot %d, pin %d, irq: %d\n",
++		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
++		slot, pin, irq);
++
++	return irq;
++}
++
++static struct hw_pci str8100_pci __initdata = {
++	.swizzle		= pci_std_swizzle,
++	.map_irq		= str8100_pci_map_irq,
++	.nr_controllers		= 1,
++	.setup			= str8100_pci_setup,
++	.scan			= str8100_pci_scan_bus,
++	.preinit		= str8100_pci_preinit,
++	.postinit		= str8100_pci_postinit,
++};
++
++static int __init str8100_pci_init(void)
++{
++	pci_common_init(&str8100_pci);
++	return 0;
++}
++
++subsys_initcall(str8100_pci_init);
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_pm.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_pm.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_pm.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_pm.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,162 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/pm.h>
++#include <linux/sched.h>
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/mach/time.h>
++#include <asm/mach/irq.h>
++
++#include <asm/mach-types.h>
++#include <linux/suspend.h>
++
++#ifdef CONFIG_PM
++/******************************************************************************
++ *
++ * FUNCTION:  Hal_Cpu_Enter_Sleep_Mode
++ * PURPOSE:   
++ *
++ ******************************************************************************/
++#ifdef CONFIG_PM_DEBUG
++#define PM_DEBUG printk
++#else
++#define PM_DEBUG(_parm,...) 
++#endif
++void inline Hal_Cpu_Enter_Sleep_Mode(void)
++{
++	__asm__ volatile (
++				"nop\n"
++				"mcr	p15, 0, r0, c7, c0, 5\n");
++}
++
++static int str8100_pm_prepare(suspend_state_t state)
++{
++	int error = 0;
++	PM_DEBUG("%s: state=%d\n",__FUNCTION__,state);
++	switch (state)
++	{
++	case PM_SUSPEND_STANDBY:
++	case PM_SUSPEND_MEM:
++		break;
++
++	default:
++		return -EINVAL;
++	}
++
++	return error;
++}
++
++extern int str8100_nic_suspend(suspend_state_t);
++extern int str8100_nic_resume(void);
++static int str8100_pm_enter(suspend_state_t state)
++{
++	PM_DEBUG("%s: state=%d\n",__FUNCTION__,state);
++	switch (state)
++	{
++	case PM_SUSPEND_STANDBY:
++	case PM_SUSPEND_MEM:
++
++#ifdef DEBUG
++		/*
++		* Configure system Xtal clock to be output to CLKOUT pin
++		*/
++		HAL_PWRMGT_CONFIGURE_CLOCK_OUT_PIN(0, 0);
++#endif
++
++		/*
++		* 1. Disable DRAM Controller's clock
++		* 2. Power-down sytem 25MHz XTAL pad
++		* 3. Force CPU into sleep mode, and wait until wake-up interrupt happens!!
++		*    When in sleep mode, CPU internal clock and system PLLs and/or 25MHZ XTAL 
++		*    pad will be power-down!!
++		*/
++
++//int 16, 18, 28-30
++//#define WAKEUP_INT 0x70050000
++//int 16, 18, 29-30
++//#define WAKEUP_INT 0x60050000
++//int 18, 29-30
++#define WAKEUP_INT 0x60040000
++//int 29-30
++//#define WAKEUP_INT 0x60000000
++//#define WAKEUP_INT 0xffffffff
++		PM_DEBUG("%s: int that can wake cpu up, WAKEUP_INT=%.8x\n",__FUNCTION__,WAKEUP_INT);
++//		HAL_INTC_SELECT_INTERRUPT_SOURCE_FOR_SLEEP_WAKEUP(30);
++		INTC_POWER_MANAGEMENT_INTERRUPT_REG=WAKEUP_INT;
++		HAL_PWRMGT_DISABLE_DRAMC_CLOCK();
++#ifndef CONFIG_STAR_NIC_PHY_INTERNAL_PHY
++		HAL_PWRMGT_POWER_DOWN_SYSTEM_XTAL_PAD();
++#endif
++
++		PM_DEBUG("%s: bye...\n",__FUNCTION__);
++		str8100_nic_suspend(state);
++		local_irq_enable();
++		Hal_Cpu_Enter_Sleep_Mode();
++		local_irq_disable();
++		str8100_nic_resume();
++		PM_DEBUG("%s: awake from sleep\n",__FUNCTION__);
++
++		break;
++
++	default:
++		return -EINVAL;
++	}
++
++	return 0;
++}
++/*
++static int str8100_pm_finish(suspend_state_t state)
++{
++printk("%s: \n",__FUNCTION__);
++	return 0;
++}
++*/
++
++static struct platform_suspend_ops str8100_pm_ops ={
++        .prepare        = str8100_pm_prepare,
++        .enter          = str8100_pm_enter,
++//		.finish         = str8100_pm_finish,
++};
++
++static int __init str8100_pm_init(void)
++{
++	int ret;
++printk("%s: \n",__FUNCTION__);
++
++    /*
++     * Configure system Xtal clock to be output to CLKOUT pin
++     */
++	HAL_PWRMGT_CONFIGURE_CLOCK_OUT_PIN(0, 0);
++
++	suspend_set_ops(&str8100_pm_ops);
++	return 0;
++}
++__initcall(str8100_pm_init);
++
++
++#endif//CONFIG_PM
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_rtc.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_rtc.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_rtc.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_rtc.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,497 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/miscdevice.h>
++#include <linux/ioport.h>
++#include <linux/fcntl.h>
++#include <linux/init.h>
++#include <linux/poll.h>
++#include <linux/proc_fs.h>
++#include <linux/spinlock.h>
++#include <linux/sysctl.h>
++#include <linux/rtc.h>
++#include <linux/interrupt.h>
++
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/system.h>
++
++#include <mach/star_rtc.h>
++#include <mach/star_intc.h>
++
++#define STR8100_RTC_DATE       "20060628"
++#define STR8100_RTC_VERSION    "1.0.0"
++#define DEVICE_NAME            "rtc"
++#define SECS_PER_HOUR   (60 * 60)
++#define SECS_PER_DAY    (SECS_PER_HOUR * 24)
++#define TM_YEAR_BASE            1900
++#define EPOCH_YEAR              1970
++#define RTC_INTR_ALARM		0x20
++
++extern spinlock_t rtc_lock;
++
++static int rtc_busy = 0;
++static unsigned long epoch = 1900;
++static unsigned int  rtc_interrupt_flag = 0;
++static time_t local_rtc_offset, set_rtc_offset, current_rtc_time;
++static DECLARE_WAIT_QUEUE_HEAD(str8100_rtc_wait);
++
++
++# define __isleap(year) ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
++
++static const unsigned char days_in_mo[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
++                                                                                
++static const unsigned short int __mon_yday[2][13] =
++{
++    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
++    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
++};
++
++static int offtime (const time_t *t, long int offset, struct rtc_time *tp)
++{
++    long int days, rem, y;
++    const unsigned short int *ip;
++				                                                                                
++    days = *t / SECS_PER_DAY;
++    rem = *t % SECS_PER_DAY;
++    rem += offset;
++    while (rem < 0)
++    {
++         rem += SECS_PER_DAY;
++   	 --days;
++    }
++    while (rem >= SECS_PER_DAY)
++    {
++         rem -= SECS_PER_DAY;
++  	 ++days;
++    }
++    tp->tm_hour = rem / SECS_PER_HOUR;
++    rem %= SECS_PER_HOUR;
++    tp->tm_min = rem / 60;
++    tp->tm_sec = rem % 60;
++    tp->tm_wday = (4 + days) % 7;
++    if (tp->tm_wday < 0)
++      tp->tm_wday += 7;
++    y = 1970;														                                                                                
++#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
++#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))							                                                                                
++    while (days < 0 || days >= (__isleap (y) ? 366 : 365))
++    {
++   	 long int yg = y + days / 365 - (days % 365 < 0);  
++   	 days -= ((yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1)- LEAPS_THRU_END_OF (y - 1));
++   	 y = yg;
++    }
++    tp->tm_year = y - 1900;
++    if (tp->tm_year != y - 1900)
++      return 0;
++    tp->tm_yday = days;
++    ip = __mon_yday[__isleap(y)];
++    for (y = 11; days < (long int) ip[y]; --y)
++       continue;
++    days -= ip[y];
++    tp->tm_mon = y;
++    tp->tm_mday = days + 1;
++    return 1;
++}
++
++static time_t ydhms_tm_diff (int year, int yday, int hour, int min, int sec, const struct rtc_time *tp)
++{
++    if (!tp) return 1;
++    else {
++      int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
++      int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
++      int a100 = a4 / 25 - (a4 % 25 < 0);
++      int b100 = b4 / 25 - (b4 % 25 < 0);
++      int a400 = a100 >> 2;
++      int b400 = b100 >> 2;
++      int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
++      time_t years = year - (time_t) tp->tm_year;
++      time_t days = (365 * years + intervening_leap_days + (yday - tp->tm_yday));
++      return (60 * (60 * (24 * days+(hour - tp->tm_hour))+(min - tp->tm_min))+(sec - tp->tm_sec));
++    }
++}
++
++static time_t _mktime(struct rtc_time *tp, time_t *offset)
++{
++    time_t t;
++    struct rtc_time tm;
++    int sec = tp->tm_sec;
++    int min = tp->tm_min;
++    int hour = tp->tm_hour;
++    int mday = tp->tm_mday;
++    int mon = tp->tm_mon;
++    int year_requested = tp->tm_year;
++
++    int mon_remainder = mon % 12;
++    int negative_mon_remainder = mon_remainder < 0;
++    int mon_years = mon / 12 - negative_mon_remainder;
++    int year = year_requested + mon_years;
++    int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
++  	       [mon_remainder + 12 * negative_mon_remainder])
++  	       + mday - 1);
++    if (year < 69) return -1;
++    tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
++    tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
++    t = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
++    if (year == 69)
++    {
++      if (t < 0 || t > 2 * 24 * 60 * 60) return -1;
++    }
++    *tp = tm;
++    return t;
++}
++
++void get_rtc_time (struct rtc_time *rtc_tm)
++{
++    time_t update_time;	
++    
++    spin_lock (&rtc_lock);
++    update_time =  RTC_SECOND_REG + RTC_MINUTE_REG * 60 + RTC_HOUR_REG * 60 * 60 + RTC_DAY_REG * 60 * 60 * 24 - local_rtc_offset + set_rtc_offset;
++    offtime(&update_time, 0, rtc_tm);	
++    if ((rtc_tm->tm_year += (epoch - 1900)) <= 69)
++      rtc_tm->tm_year += 100; 
++    spin_unlock (&rtc_lock);
++}
++
++int set_rtc_time (struct rtc_time *rtc_tm)
++{
++    unsigned char mon, day, hrs, min, sec, leap_yr;
++    unsigned int yrs;
++    
++    spin_lock (&rtc_lock);
++    yrs = rtc_tm->tm_year + 1900;
++    mon = rtc_tm->tm_mon + 1;  
++    day = rtc_tm->tm_mday;
++    hrs = rtc_tm->tm_hour;
++    min = rtc_tm->tm_min;
++    sec = rtc_tm->tm_sec; 
++    if (yrs < 1970) return -EINVAL;
++    leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
++    if ((mon > 12) || (day == 0)) return -EINVAL;
++    if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) return -EINVAL;
++    if ((hrs >= 24) || (min >= 60) || (sec >= 60)) return -EINVAL;
++    if ((yrs -= epoch) > 255) return -EINVAL;   
++    local_rtc_offset = RTC_SECOND_REG + RTC_MINUTE_REG * 60 + RTC_HOUR_REG * 60 * 60 + RTC_DAY_REG * 60 * 60 * 24;
++    set_rtc_offset = _mktime(rtc_tm, 0);
++    spin_unlock (&rtc_lock);
++    return 0;
++}
++
++int set_rtc_alm_time (struct rtc_time *alm_tm)
++{
++    unsigned char hrs, min, sec;
++    unsigned long alm_sec;
++    unsigned int volatile rtc_int_status;
++    
++    spin_lock_irq(&rtc_lock);
++    alm_sec = alm_tm->tm_hour * 3600 + alm_tm->tm_min * 60 + alm_tm->tm_sec;
++    hrs = alm_sec / 3600;
++    min = (alm_sec % 3600) / 60;
++    sec = (alm_sec % 3600) % 60;
++    RTC_HOUR_ALARM_REG = hrs;
++    RTC_MINUTE_ALARM_REG = min;
++    RTC_SECOND_ALARM_REG = sec;
++    RTC_CONTROL_REG = RTC_MATCH_ALARM_ENABLE_BIT;
++    rtc_int_status = RTC_INTERRUPT_STATUS_REG;
++    RTC_INTERRUPT_STATUS_REG = rtc_int_status;                      
++    spin_unlock_irq(&rtc_lock);    
++    return 0;
++}
++
++static loff_t rtc_lseek(struct file *file, loff_t offset, int origin)
++{
++    return -ESPIPE;
++}
++
++static void mask_rtc_irq_bit(unsigned char bit)
++{
++    unsigned char val;
++    unsigned int volatile rtc_int_status;
++
++    spin_lock_irq(&rtc_lock);
++    val = RTC_CONTROL_REG;
++    val &=  ~bit;
++    RTC_CONTROL_REG = val;
++    rtc_int_status = RTC_INTERRUPT_STATUS_REG;
++    spin_unlock_irq(&rtc_lock);
++}
++
++static void set_rtc_irq_bit(unsigned char bit)
++{
++    unsigned char val;
++    unsigned int volatile rtc_int_status;	
++        
++    spin_lock_irq(&rtc_lock);
++    val = RTC_CONTROL_REG;
++    val |= bit;
++    RTC_CONTROL_REG = val;
++    rtc_int_status = RTC_INTERRUPT_STATUS_REG;
++    spin_unlock_irq(&rtc_lock);
++}
++
++static void get_rtc_alm_time(struct rtc_time *alm_tm)
++{
++    spin_lock_irq(&rtc_lock);
++    alm_tm->tm_sec = RTC_SECOND_ALARM_REG;
++    alm_tm->tm_min = RTC_MINUTE_ALARM_REG;
++    alm_tm->tm_hour = RTC_HOUR_ALARM_REG;
++    spin_unlock_irq(&rtc_lock);
++}
++
++static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,unsigned long arg)
++{
++    struct rtc_time wtime; 
++
++    switch (cmd)
++    {
++	case RTC_RD_TIME:
++	        memset(&wtime, 0, sizeof(struct rtc_time));
++		get_rtc_time(&wtime);
++		break;
++	case RTC_SET_TIME:
++	{         
++		struct rtc_time rtc_tm;
++		if (!capable(CAP_SYS_TIME))
++		  return -EPERM;
++		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
++		  return -EFAULT;
++		set_rtc_time(&rtc_tm);
++		return 0;
++	}	
++        case RTC_ALM_SET:
++        {
++        	struct rtc_time alm_tm; 
++		if (copy_from_user(&alm_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
++		  return -EFAULT;
++		memset(&wtime, 0, sizeof(struct rtc_time));  
++		set_rtc_alm_time(&alm_tm);
++		return 0;
++	}	
++	case RTC_ALM_READ:
++	        memset(&wtime, 0, sizeof(struct rtc_time));
++		get_rtc_alm_time(&wtime);
++		break;
++	case RTC_AIE_OFF:
++	        mask_rtc_irq_bit(RTC_INTR_ALARM);	
++		return 0;
++	case RTC_AIE_ON:
++	        set_rtc_irq_bit(RTC_INTR_ALARM);
++		return 0;	
++	default:
++		return -EINVAL;
++    }
++    return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
++}
++
++// Eileen , for linux kernel 2.6.24 , 20080417
++// old : static irqreturn_t rtc_fire(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t rtc_fire(int irq, void *dev_id)
++{
++    unsigned int volatile    rtc_int_status;	
++    
++    HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_RTC_BIT_INDEX);
++    HAL_RTC_READ_INTERRUPT_STATUS(rtc_int_status);
++    HAL_RTC_WRITE_INTERRUPT_STATUS(rtc_int_status);
++//    HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_RTC_BIT_INDEX);
++//    return IRQ_HANDLED; 
++    if (rtc_int_status & RTC_AUTO_SECOND_ALARM_INTR_BIT) rtc_interrupt_flag |= RTC_AUTO_SECOND_ALARM_INTR_BIT;
++    if (rtc_int_status & RTC_AUTO_MINUTE_ALARM_INTR_BIT) rtc_interrupt_flag |= RTC_AUTO_MINUTE_ALARM_INTR_BIT;
++    if (rtc_int_status & RTC_AUTO_HOUR_ALARM_INTR_BIT) rtc_interrupt_flag |= RTC_AUTO_HOUR_ALARM_INTR_BIT;
++    if (rtc_int_status & RTC_AUTO_DAY_ALARM_INTR_BIT) rtc_interrupt_flag |= RTC_AUTO_DAY_ALARM_INTR_BIT;
++    if (rtc_int_status & RTC_MATCH_ALARM_INTR_BIT) {rtc_interrupt_flag |= RTC_MATCH_ALARM_INTR_BIT;
++      wake_up_interruptible(&str8100_rtc_wait);
++    }
++    if (rtc_int_status & RTC_BATTERY_LOW_VOLTAGE_INTR_BIT)
++    {
++    	rtc_interrupt_flag |= RTC_BATTERY_LOW_VOLTAGE_INTR_BIT;
++        printk(" str8100 rtc: Low Battery Voltage!!\n");
++    }
++    if (!(rtc_interrupt_flag & RTC_MATCH_ALARM_INTR_BIT)) HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_RTC_BIT_INDEX);
++
++    return IRQ_HANDLED; 
++}
++
++static void rtc_str8100_hwinit(int ctrl, int hour, int min, int sec)
++{    	
++    RTC_CONTROL_REG &= ~(RTC_ENABLE_BIT);	
++    if (ctrl & RTC_MATCH_ALARM_ENABLE_BIT)
++    {
++      RTC_SECOND_ALARM_REG = sec;
++      RTC_MINUTE_ALARM_REG = min;
++      RTC_HOUR_ALARM_REG = hour;    	
++    }else{
++      RTC_SECOND_ALARM_REG = 0;
++      RTC_MINUTE_ALARM_REG = 0;
++      RTC_HOUR_ALARM_REG = 0;
++    } 
++    RTC_CONTROL_REG = ctrl;
++} 
++
++static int rtc_open(struct inode *inode, struct file *file)
++{
++    if (rtc_busy) return -EBUSY;
++
++    rtc_busy = 1;
++    return 0;
++}
++
++static ssize_t rtc_read(struct file * file, char *buf, size_t count, loff_t * ppos)
++{
++    DECLARE_WAITQUEUE(wait, current);
++    unsigned long data;
++    ssize_t retval;
++
++    if (count < sizeof(unsigned long))
++      return -EINVAL;
++
++    add_wait_queue(&str8100_rtc_wait, &wait);
++    set_current_state(TASK_INTERRUPTIBLE);
++    for (;;) {
++	spin_lock(&rtc_lock);
++	data = rtc_interrupt_flag;
++	if (data != 0) {
++	  rtc_interrupt_flag = 0;
++	  break;
++	}
++        spin_unlock(&rtc_lock);
++        if (file->f_flags & O_NONBLOCK) {
++	  retval = -EAGAIN;
++	  goto out;
++	}
++	if (signal_pending(current)) {
++	  retval = -ERESTARTSYS;
++	  goto out;
++	}
++        schedule();
++    }
++    spin_unlock(&rtc_lock);
++    retval = put_user(data, (unsigned long *) buf);
++    if (!retval) retval = sizeof(unsigned long);
++out:
++    mask_rtc_irq_bit(RTC_INTR_ALARM);
++    set_current_state(TASK_RUNNING);
++    remove_wait_queue(&str8100_rtc_wait, &wait);
++    return retval;
++}
++
++static int rtc_release(struct inode *inode, struct file *file)
++{
++    rtc_busy = 0;
++    return 0;
++}
++
++static struct file_operations rtc_fops = {
++    owner:	THIS_MODULE,
++    llseek:	rtc_lseek,
++    ioctl:	rtc_ioctl,
++    open:	rtc_open,
++    read:       rtc_read,
++    release:	rtc_release
++};
++
++static struct miscdevice rtc_dev = { RTC_MINOR, "rtc", &rtc_fops };
++
++static int rtc_proc_output (char *buf)
++{
++    char *p;
++    struct rtc_time tm;
++    
++    p = buf;
++    get_rtc_time(&tm);
++    p += sprintf(p,"rtc_time\t: %02d:%02d:%02d\n"
++		   "rtc_date\t: %04d-%02d-%02d\n"
++	 	   "rtc_epoch\t: %04lu\n",
++		   tm.tm_hour, tm.tm_min, tm.tm_sec,
++		   tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
++    get_rtc_alm_time(&tm);
++    p += sprintf(p, "alarm\t\t: ");
++    if (tm.tm_hour <= 24)
++      p += sprintf(p, "%02d:", tm.tm_hour);
++    else
++      p += sprintf(p, "**:");
++    if (tm.tm_min <= 59)
++      p += sprintf(p, "%02d:", tm.tm_min);
++    else
++      p += sprintf(p, "**:");
++    if (tm.tm_sec <= 59)
++      p += sprintf(p, "%02d\n", tm.tm_sec);
++    else
++      p += sprintf(p, "**\n");	
++    return  p - buf;
++}
++
++static int rtc_read_proc(char *page, char **start, off_t off,int count, int *eof, void *data)
++{
++    int len = rtc_proc_output (page);
++    
++    if (len <= off+count) *eof = 1;
++    *start = page + off;
++    len -= off;
++    if (len>count) len = count;
++    if (len<0) len = 0;
++    return len;
++}
++
++static int __init str8100_rtc_init(void)
++{
++    int error;
++
++    error = misc_register(&rtc_dev);
++    if (error) {
++      printk(KERN_ERR "rtc: unable to get misc minor\n");
++      return error;
++    }	
++    printk(KERN_INFO "str8100_rtc.o: rtc module version %s\n", STR8100_RTC_VERSION);
++    rtc_str8100_hwinit(0,0,0,0);
++    HAL_RTC_ENABLE();
++    request_irq(INTC_RTC_BIT_INDEX, rtc_fire, 0, DEVICE_NAME, NULL);
++    create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL);
++    local_rtc_offset = 0;
++    set_rtc_offset = current_rtc_time = 0;        
++    return 0;
++}
++
++static void __exit str8100_rtc_exit (void)
++{
++    char buf[64];
++    	
++    HAL_RTC_DISABLE();		
++    // Eileen , for linux kernel 2.6.24 , 20080417
++    // cleanup_sysctl();
++    sprintf (buf,"driver/%s",DEVICE_NAME);
++    remove_proc_entry (buf, NULL);
++    misc_deregister(&rtc_dev);
++    free_irq (INTC_RTC_BIT_INDEX, NULL);
++}
++
++module_init(str8100_rtc_init);
++module_exit(str8100_rtc_exit);
++// Eileen , for linux kernel 2.6.24 , 20080417
++//EXPORT_NO_SYMBOLS;
++
++MODULE_AUTHOR("Rober Hsu");
++MODULE_LICENSE("GPL");
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_setup.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_setup.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_setup.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_setup.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,569 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/mm.h>
++#include <linux/init.h>
++//#include <linux/config.h>
++#include <linux/major.h>
++#include <linux/fs.h>
++#include <linux/platform_device.h>
++#include <linux/serial.h>
++#include <linux/tty.h>
++#include <linux/serial_8250.h>
++#ifdef CONFIG_SPI_STR8100
++#include <mach/star_spi.h>
++#include <linux/spi/spi.h>
++#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
++#include <linux/spi/flash.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#endif
++#endif // CONFIG_SPI_STR8100
++
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/page.h>
++#include <asm/mach/map.h>
++#include <asm/setup.h>
++#include <asm/system.h>
++#include <asm/memory.h>
++#include <mach/hardware.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++
++
++
++#if 1 // on ASIC
++#define STR8100_UART_XTAL 24000000
++#else // on FPGA
++#define STR8100_UART_XTAL 13000000
++#endif
++
++#define EARLY_REGISTER_CONSOLE
++#define DEVICE_REGISTER_MULTIPLE
++
++/*
++ * Standard IO mapping
++ */
++static struct map_desc str8100_std_desc[] __initdata = {
++	{
++		.virtual	= SYSVA_FLASH_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_FLASH_SRAM_BANK0_BASE_ADDR),
++		.length		= SZ_8M,
++		.type		= MT_DEVICE
++	}, 	{
++		.virtual	= SYSVA_IDE_DEVICE_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_IDE_DEVICE_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_GDMAC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_GDMAC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_NIC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_NIC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_SPI_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_SPI_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_PCM_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_PCM_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_I2C_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_I2C_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_I2S_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_I2S_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_DDRC_SDRC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_DDRC_SDRC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_SMC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_SMC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_IDE_CONTROLLER_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_IDE_CONTROLLER_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_MISC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_MISC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_POWER_MANAGEMENT_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_POWER_MANAGEMENT_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_UART0_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_UART0_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_UART1_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_UART1_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_TIMER_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_TIMER_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_WATCHDOG_TIMER_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_WATCHDOG_TIMER_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_RTC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_RTC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_GPIOA_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_GPIOA_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_GPIOB_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_GPIOB_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB11_CONFIG_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB11_CONFIG_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB11_OPERATION_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB11_OPERATION_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB20_CONFIG_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB20_CONFIG_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB20_OPERATION_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB20_OPERATION_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB20_DEVICE_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB20_DEVICE_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_VIC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_VIC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}
++};
++
++#ifdef EARLY_REGISTER_CONSOLE
++static struct uart_port str8100_serial_ports[] = {
++	{
++		.membase	= (char*)(SYSVA_UART0_BASE_ADDR),
++		.mapbase	= (SYSPA_UART0_BASE_ADDR),
++		.irq		= INTC_UART0_BIT_INDEX,
++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++		.iotype		= UPIO_MEM,
++		.regshift	= 2,
++		.uartclk	= STR8100_UART_XTAL,
++		.line		= 0,
++		.type		= PORT_16550A,
++		.fifosize	= 16
++	} , {
++		.membase	= (char*)(SYSVA_UART1_BASE_ADDR),
++		.mapbase	= (SYSPA_UART1_BASE_ADDR),
++		.irq		= INTC_UART1_BIT_INDEX,
++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++		.iotype		= UPIO_MEM,
++		.regshift	= 2,
++		.uartclk	= STR8100_UART_XTAL,
++		.line		= 1,
++		.type		= PORT_16550A,
++		.fifosize	= 16
++	}
++};
++#else
++static struct resource str8100_uart0_resources[] = {
++	[0] = {
++		.start	= SYSPA_UART0_BASE_ADDR,
++		.end	= SYSPA_UART0_BASE_ADDR + 0xff,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_UART0_BIT_INDEX,
++		.end	= INTC_UART0_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ
++	}
++};
++
++static struct resource str8100_uart1_resources[] = {
++	[0] = {
++		.start	= SYSPA_UART1_BASE_ADDR,
++		.end	= SYSPA_UART1_BASE_ADDR + 0xff,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_UART1_BIT_INDEX,
++		.end	= INTC_UART1_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ
++	}
++};
++
++static struct plat_serial8250_port str8100_uart0_data[] = {
++	{
++		.membase	= (char*)(SYSVA_UART0_BASE_ADDR),
++		.mapbase	= (SYSPA_UART0_BASE_ADDR),
++		.irq		= INTC_UART0_BIT_INDEX,
++		.uartclk	= STR8100_UART_XTAL,
++		.regshift	= 2,
++		.iotype		= UPIO_MEM,
++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++	},
++	{  },
++};
++
++static struct plat_serial8250_port str8100_uart1_data[] = {
++	{
++		.membase	= (char*)(SYSVA_UART1_BASE_ADDR),
++		.mapbase	= (SYSPA_UART1_BASE_ADDR),
++		.irq		= INTC_UART1_BIT_INDEX,
++		.uartclk	= STR8100_UART_XTAL,
++		.regshift	= 2,
++		.iotype		= UPIO_MEM,
++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++	},
++	{  },
++};
++
++static struct platform_device str8100_uart0_device = {
++	.name = "serial8250",
++	.id = 0,
++	.dev.platform_data = str8100_uart0_data,
++	.num_resources = 2,
++	.resource = str8100_uart0_resources,
++};
++
++static struct platform_device str8100_uart1_device = {
++	.name = "serial8250",
++	.id = 1,
++	.dev.platform_data = str8100_uart1_data,
++	.num_resources = 2,
++	.resource = str8100_uart1_resources,
++};
++#endif
++
++
++static u64 usb_dmamask = 0xffffffffULL;
++static struct resource str8100_usb11_resources[] = {
++	[0] = {
++		.start	= SYSPA_USB11_CONFIG_BASE_ADDR,
++		.end	= SYSPA_USB11_CONFIG_BASE_ADDR + SZ_1M - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_USB11_BIT_INDEX,
++		.end	= INTC_USB11_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device str8100_usb11_device = {
++	.name		= "str8100-ohci",
++	.id		= -1,
++	.dev = {
++		.dma_mask		= &usb_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.resource	= str8100_usb11_resources,
++	.num_resources	= ARRAY_SIZE(str8100_usb11_resources),
++};
++
++static struct resource str8100_usb20_resources[] = {
++	[0] = {
++		.start	= SYSPA_USB20_CONFIG_BASE_ADDR,
++		.end	= SYSPA_USB20_CONFIG_BASE_ADDR + SZ_1M - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_USB20_BIT_INDEX,
++		.end	= INTC_USB20_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device str8100_usb20_device = {
++	.name		= "str8100-ehci",
++	.id		= -1,
++	.dev		= {
++		.dma_mask		= &usb_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.resource	= str8100_usb20_resources,
++	.num_resources	= ARRAY_SIZE(str8100_usb20_resources),
++};
++
++#ifdef CONFIG_SPI_STR8100
++#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
++static struct mtd_partition str8100_spi_flash_partitions[] = {
++	{
++		.name =		"all",
++		.offset =	CONFIG_ARMBOOT_OFFSET,
++		.size =		0x800000-CONFIG_ARMBOOT_OFFSET,
++	},{
++		.name =		"ARMBOOT",
++		.offset =	CONFIG_ARMBOOT_OFFSET,
++		.size =		CONFIG_KERNEL_OFFSET-CONFIG_ARMBOOT_OFFSET,
++	},{
++		.name =		"Linux Kernel",
++		.offset =	CONFIG_KERNEL_OFFSET,
++		.size =		CONFIG_ROOTFS_OFFSET-CONFIG_KERNEL_OFFSET,
++	},{
++		.name =		"MTD Disk1",
++		.offset =	CONFIG_ROOTFS_OFFSET,
++		.size =		CONFIG_CFG_OFFSET-CONFIG_ROOTFS_OFFSET,
++	},{
++		.name =		"MTD Disk2",
++		.offset =	CONFIG_CFG_OFFSET,
++		.size =		0x800000-CONFIG_CFG_OFFSET,
++	}
++};
++
++static struct flash_platform_data str8100_spi_flash_data = {
++	.name = "m25p80",
++	.parts = str8100_spi_flash_partitions,
++	.nr_parts = ARRAY_SIZE(str8100_spi_flash_partitions),
++	.type = "m25p64",
++};
++
++#if defined(CONFIG_LE88221_CONTROL)
++static struct str8100_spi_dev_attr str8100_spi_le88221_attr = {
++	.spi_serial_mode = STR8100_SPI_SERIAL_MODE_MICROPROCESSOR,
++};
++#endif
++
++static struct spi_board_info str8100_spi_board_info[] = {
++        {
++		.modalias	= "m25p80",
++		.chip_select	= 0,
++		.max_speed_hz	= 25 * 1000 * 1000,
++		.bus_num	= 1,
++		.platform_data = &str8100_spi_flash_data,
++        },
++
++#if defined(CONFIG_LE88221_CONTROL)
++	{
++		.modalias	= "le88221",
++		.chip_select	= 1,
++		.max_speed_hz	= 25 * 1000 * 1000,
++		.bus_num	= 1,
++		.platform_data	= NULL,
++		.controller_data = &str8100_spi_le88221_attr,
++        },
++#endif
++};
++#endif
++
++static u64 spi_dmamask = 0xffffffffUL;
++static struct resource str8100_spi_resources[] = {
++	[0] = {
++		.start	= SYSPA_SPI_BASE_ADDR,
++		.end	= SYSPA_SPI_BASE_ADDR + SZ_4K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_SPI_BIT_INDEX,
++		.end	= INTC_SPI_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device str8100_spi_master_device = {
++	.name		= "str8100_spi",
++	.id		= -1,
++	.dev		= {
++		.dma_mask		= &spi_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.resource	= str8100_spi_resources,
++	.num_resources	= ARRAY_SIZE(str8100_spi_resources),
++};
++#endif // CONFIG_SPI_STR8100
++
++#ifdef DEVICE_REGISTER_MULTIPLE
++static struct platform_device *str8100_devices[] __initdata = {
++#ifndef EARLY_REGISTER_CONSOLE
++	&str8100_uart0_device,
++	&str8100_uart1_device,
++#endif
++#ifdef CONFIG_SPI_STR8100
++	&str8100_spi_master_device,
++#endif
++	&str8100_usb11_device,
++	&str8100_usb20_device
++};
++#endif
++
++static void __init str8100_fixup(struct machine_desc *desc,
++	struct tag *tags, char **cmdline, struct meminfo *mi)
++{      
++   mi->nr_banks = 1;
++	mi->bank[0].start = CONFIG_SYSTEM_DRAM_BASE;
++	mi->bank[0].size = CONFIG_SYSTEM_DRAM_SIZE << 20;
++	//mi->bank[0].node = 0;
++}
++
++/* ######################################################################### */
++#ifdef CONFIG_CPU_ISPAD_ENABLE 
++extern unsigned long __ispad_begin; 
++#endif
++u32 PLL_clock;
++u32 CPU_clock;
++u32 AHB_clock;
++u32 APB_clock;
++EXPORT_SYMBOL(PLL_clock);
++EXPORT_SYMBOL(CPU_clock);
++EXPORT_SYMBOL(AHB_clock);
++EXPORT_SYMBOL(APB_clock);
++// This function is called just after the
++// page table and cpu have been initialized
++
++#include "asm/procinfo.h"
++#include "asm/cacheflush.h"
++#include "asm/system.h"
++void __init str8100_early_init(void)
++{
++   //printk("str8100_early_init()\n");
++        
++	switch (PWRMGT_SYSTEM_CLOCK_CONTROL_REG & 0x3) {
++	case 0x0:
++		PLL_clock = 175000000;
++		break;
++	case 0x1:
++		PLL_clock = 200000000;
++		break;
++	case 0x2:
++		PLL_clock = 225000000;
++		break;
++	case 0x3:
++		PLL_clock = 250000000;
++		break;
++	}
++
++	CPU_clock = PLL_clock / (((PWRMGT_SYSTEM_CLOCK_CONTROL_REG >> 2) & 0x3) + 1);
++	AHB_clock = CPU_clock / (((PWRMGT_SYSTEM_CLOCK_CONTROL_REG >> 4) & 0x3) + 1);
++	APB_clock = AHB_clock / (((PWRMGT_SYSTEM_CLOCK_CONTROL_REG >> 8) & 0x3) + 1);
++
++	printk("PLL clock at %dMHz\n", PLL_clock / 1000000);
++	printk("CPU clock at %dMHz\n", CPU_clock / 1000000);
++	printk("AHB clock at %dMHz\n", AHB_clock / 1000000);
++	printk("APB clock at %dMHz\n", APB_clock / 1000000);
++}
++/* ######################################################################### */
++
++void __init str8100_init(void)
++{
++//   printk("str8100_init()\n");
++   
++#ifdef DEVICE_REGISTER_MULTIPLE
++	platform_add_devices(str8100_devices, ARRAY_SIZE(str8100_devices));
++#ifdef CONFIG_SPI_STR8100
++#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
++	spi_register_board_info(str8100_spi_board_info, ARRAY_SIZE(str8100_spi_board_info));
++#endif
++#endif // CONFIG_SPI_STR8100
++#else // DEVICE_REGISTER_MULTIPLE
++#ifndef EARLY_REGISTER_CONSOLE
++	platform_device_register(&str8100_uart0_device);
++	platform_device_register(&str8100_uart1_device);
++#endif
++#ifdef CONFIG_SPI_STR8100
++	platform_device_register(&str8100_spi_master_device);
++#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
++	spi_register_board_info(str8100_spi_board_info, ARRAY_SIZE(str8100_spi_board_info));
++#endif
++#endif
++	platform_device_register(&str8100_usb11_device);
++	platform_device_register(&str8100_usb20_device);
++#endif
++}
++
++extern void str8100_register_map_desc(struct map_desc *map, int count);
++void __init str8100_map_io(void)
++{
++//   printk("str8100_map_io()\n");
++   
++	iotable_init(str8100_std_desc, ARRAY_SIZE(str8100_std_desc));
++	str8100_register_map_desc(str8100_std_desc, ARRAY_SIZE(str8100_std_desc));
++#ifdef EARLY_REGISTER_CONSOLE
++	early_serial_setup(&str8100_serial_ports[0]);
++	early_serial_setup(&str8100_serial_ports[1]);
++#endif
++}
++
++extern void str8100_init_irq(void);
++extern struct sys_timer str8100_timer;
++
++MACHINE_START(STR8100, "STAR STR8100")
++	.phys_io	= SYSPA_UART0_BASE_ADDR,
++	.io_pg_offst	= ((SYSVA_UART0_BASE_ADDR) >> 18) & 0xfffc, // virtual, physical
++	.fixup		= str8100_fixup,
++	.map_io		= str8100_map_io,
++	.init_irq	= str8100_init_irq,
++	.timer		= &str8100_timer,
++	.boot_params	= 0x0100,
++	.init_machine	= str8100_init,
++MACHINE_END
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_timer.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_timer.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_timer.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_timer.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,224 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/time.h>
++#include <linux/init.h>
++#include <linux/timex.h>
++
++#include <mach/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/time.h>
++
++#if 1
++// for timer clock < 100MHz
++#define uSECS_PER_TICK	(1000000 / APB_clock)
++#define TICKS2USECS(x)  ((x) * uSECS_PER_TICK)
++#else
++// for timer clock >= 100MHz
++#define TICKS_PER_uSEC	(APB_clock / 1000000)
++#define TICKS2USECS(x)  ((x) / TICKS_PER_uSEC)
++#endif
++
++extern u32 APB_clock;
++static u32 timer_counter_value;
++
++static inline unsigned int str8100_read_timer_counter(void)
++{
++	return TIMER1_COUNTER_REG;
++}
++
++static inline unsigned int str8100_read_timer_interrupt_status(void)
++{
++	return TIMER1_TIMER2_INTERRUPT_STATUS_REG;
++}
++
++static inline void str8100_clear_timer_interrupt_status(unsigned int irq)
++{
++	TIMER1_TIMER2_INTERRUPT_STATUS_REG &= ~(1 << TIMER1_OVERFLOW_INTERRUPT_BIT_INDEX);
++}
++
++static void str8100_setup_timer(unsigned int counter_value)
++{
++	unsigned long control_value;
++	unsigned long mask_value;    
++
++	control_value = TIMER1_TIMER2_CONTROL_REG;
++	mask_value = TIMER1_TIMER2_INTERRUPT_MASK_REG;
++
++	TIMER1_COUNTER_REG = counter_value;
++	TIMER1_AUTO_RELOAD_VALUE_REG = counter_value;
++	TIMER1_MATCH_VALUE1_REG = 0;
++	TIMER1_MATCH_VALUE2_REG = 0;
++
++	// Clock Source: PCLK
++	control_value &= ~(1 << TIMER1_CLOCK_SOURCE_BIT_INDEX);
++
++	// Down Count Mode
++	control_value |= (1 << TIMER1_UP_DOWN_COUNT_BIT_INDEX);
++
++	// un-mask overflow, match2 and match1 interrupt sources
++	mask_value &= ~(0x7);
++
++	// mask match2 and match1 interrupt sources
++	mask_value |= 0x03;
++
++	TIMER1_TIMER2_CONTROL_REG = control_value;
++	TIMER1_TIMER2_INTERRUPT_MASK_REG = mask_value;
++}
++
++static void str8100_timer_enable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER1_TIMER2_CONTROL_REG;
++
++	// enable overflow mode
++	control_value |= (1 << TIMER1_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// enable the timer
++	control_value |= (1 << TIMER1_ENABLE_BIT_INDEX);
++
++	TIMER1_TIMER2_CONTROL_REG = control_value;
++}
++
++static void str8100_timer_disable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER1_TIMER2_CONTROL_REG;
++
++	// disable overflow mode
++	control_value &= ~(1 << TIMER1_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// disable the timer
++	control_value &= ~(1 << TIMER1_ENABLE_BIT_INDEX);
++
++	TIMER1_TIMER2_CONTROL_REG = control_value;
++}
++
++/*
++ * Returns number of us since last clock interrupt.  Note that interrupts
++ * will have been disabled by do_gettimeoffset()
++ */
++static unsigned long str8100_gettimeoffset(void)
++{
++	unsigned long ticks1, ticks2;
++	unsigned long interrupt_status;
++
++	/*
++	 * Get the current number of ticks.  Note that there is a race
++	 * condition between us reading the timer and checking for
++	 * an interrupt.  We get around this by ensuring that the
++	 * counter has not reloaded between our two reads.
++	 */
++	ticks2 = str8100_read_timer_counter();
++	do {
++		ticks1 = ticks2;
++		interrupt_status = str8100_read_timer_interrupt_status();
++		ticks2 = str8100_read_timer_counter();
++	} while (ticks2 > ticks1);
++
++	/*
++	 * Number of ticks since last interrupt
++	 */
++	ticks1 = timer_counter_value - ticks2;
++
++	/*
++	 * Interrupt pending?  If so, we've reloaded once already.
++	 */
++	if (interrupt_status) {
++		ticks1 += timer_counter_value;
++	}
++
++	/*
++	 * Convert the ticks to usecs
++	 */
++	return TICKS2USECS(ticks1);
++}
++
++/*
++ * IRQ handler for the timer
++ */
++static irqreturn_t
++str8100_timer_interrupt(int irq, void *dev_id /*, struct pt_regs *regs*/)
++{     
++  		
++#ifndef CONFIG_VIC_INTERRUPT
++	str8100_clear_timer_interrupt_status((unsigned int)irq);
++#endif
++	/* scot.patch
++	timer_tick(regs);
++	*/
++	timer_tick();
++		
++	return IRQ_HANDLED;
++}
++
++static struct irqaction str8100_timer_irq = {
++	.name		= "STR8100 Timer Tick",
++/* scott.patch
++	.flags		= SA_INTERRUPT | SA_TIMER,
++*/
++	.flags		= IRQF_DISABLED | IRQF_TIMER, 
++	.handler	= str8100_timer_interrupt,
++};
++
++/*
++ * Set up timer interrupt, and return the current time in seconds.
++ */
++ 
++
++static void __init str8100_timer_init(void)
++{
++	/*
++	 * prepare timer-related values
++	 */
++	timer_counter_value = APB_clock / HZ;
++
++	/*
++	 * setup timer-related values
++	 */
++	str8100_setup_timer(timer_counter_value);
++
++	
++	/*
++	 * Make irqs happen for the system timer
++	 */
++	setup_irq(INTC_TIMER1_BIT_INDEX, &str8100_timer_irq);
++
++	str8100_timer_enable();
++		
++	
++}
++
++struct sys_timer str8100_timer = {
++	.init		= str8100_timer_init,
++#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET	
++	.offset		= str8100_gettimeoffset,
++#endif	
++};
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/Kconfig linux-2.6.35.11-ts7500/arch/arm/mach-str9100/Kconfig
+--- linux-2.6.35.11/arch/arm/mach-str9100/Kconfig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,99 @@
++if ARCH_STR9100
++
++menu "STR9100 Options"
++
++config CONSOLE_BAUD_RATE
++	int "Console Baud Rate"
++	default 115200
++	help
++	  set the console baudrate
++
++config CPU_ISPAD_ENABLE
++	bool "Enable I-Scratch Pad Support"
++	default y
++	help
++	  enable I-Scratch Pad support
++
++choice
++	prompt "DRAM SIZE"
++	default STR9100_DRAM_16M
++
++config STR9100_DRAM_16M
++	bool "16MBytes"
++
++config STR9100_DRAM_32M
++	bool "32MBytes"
++
++config STR9100_DRAM_64M
++	bool "64MBytes"
++
++endchoice
++
++if PCI
++choice
++	prompt "PCI Frequency"
++	default STAR9100_PCI33M
++
++config STR9100_PCI33M
++	bool "PCI_33Mhz"
++
++config STR9100_PCI66M
++	bool "PCI_66Mhz"
++
++endchoice
++endif
++
++config STR9100_RTC
++	bool "STR9100 Real Time Clock Support"
++
++config STR9100_GPIO
++	bool "STR9100 GPIO Support"
++
++config STR9100_GPIO_INTERRUPT
++	bool "Interrupt Library Support"
++	depends on STR9100_GPIO
++
++config STR9100_INFO
++	bool "STR9100 Infomation at /proc/str9100/info"
++
++comment "Flash MAP"
++config STR9100_FLASH_PART
++	bool "STR9100 flash partition setting"
++
++if STR9100_FLASH_PART
++	config ARMBOOT_OFFSET
++	hex "ARMBOOT OFFSET"
++	default 0x0
++	help
++	  The armboot start offset in flash layout
++
++	config KERNEL_OFFSET
++	hex "KERNEL OFFSET"
++	default 0x40000
++	help
++	  The kernel start offset in flash layout
++
++	config ROOTFS_OFFSET
++	hex "ROOTFS OFFSET"
++	default 0x140000
++	help
++	  The rootfs start offset in flash layout
++
++	config CFG_OFFSET
++	hex "CFG OFFSET"
++	default 0x7f0000
++	help
++	  The cfg start offset in flash layout
++endif
++
++comment "Third Party Support"
++
++config STR9100_EWC_SUPPORT
++	bool "EWC(802.11N) Support"
++
++config SWITCH_IOCTL
++	bool "SUPPORT SWITCH IOCTL"
++
++endmenu
++
++endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/Makefile linux-2.6.35.11-ts7500/arch/arm/mach-str9100/Makefile
+--- linux-2.6.35.11/arch/arm/mach-str9100/Makefile	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,14 @@
++#
++# Makefile for the linux kernel.
++#
++
++# Object file lists.
++
++obj-y			:= str9100_debug.o str9100_setup.o str9100_timer.o str9100_intc.o str9100_counter.o str9100_misc.o
++obj-m			:=
++obj-n			:=
++obj-			:=
++
++obj-$(CONFIG_PCI) += str9100_pci.o
++obj-$(CONFIG_STR9100_GPIO)	+= str9100_gpio.o
++obj-$(CONFIG_STR9100_RTC)	+= str9100_rtc.o
+\ No newline at end of file
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/Makefile.boot linux-2.6.35.11-ts7500/arch/arm/mach-str9100/Makefile.boot
+--- linux-2.6.35.11/arch/arm/mach-str9100/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/Makefile.boot	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,10 @@
++# Note: the following conditions must always be true:
++#   ZRELADDR == virt_to_phys(TEXTADDR)
++#   PARAMS_PHYS must be within 4MB of ZRELADDR
++#   INITRD_PHYS must be in RAM
++
++   zreladdr-y	:= 0x00008000
++params_phys-y	:= 0x00000100
++initrd_phys-y	:= 0x00C00000
++kernel_phys-y	:= 0x00400000
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_counter.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_counter.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_counter.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_counter.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,214 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/time.h>
++#include <linux/init.h>
++#include <linux/timex.h>
++#include <linux/proc_fs.h>
++#include <linux/module.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/time.h>
++
++u64 volatile str9100_counter_tick;
++EXPORT_SYMBOL(str9100_counter_tick);
++
++static struct proc_dir_entry *str9100_counter_proc_entry;
++
++#if 0
++// this is defined in include/asm/arch-str9100/system.h
++u64 str9100_read_counter(void)
++{
++	return (str9100_counter_tick + TIMER2_COUNTER_REG);
++}
++EXPORT_SYMBOL(str9100_read_counter);
++#endif
++
++static int match1=0;
++static int match2=0;
++static void str9100_setup_counter(void)
++{
++	unsigned long control_value;
++	unsigned long mask_value;    
++	unsigned long val;    
++
++	control_value = TIMER_CONTROL_REG;
++	mask_value = TIMER_INTERRUPT_MASK_REG;
++
++	TIMER2_COUNTER_REG		= 0;
++	TIMER2_AUTO_RELOAD_VALUE_REG	= 0;
++	TIMER2_MATCH_VALUE1_REG		= match1;
++	TIMER2_MATCH_VALUE2_REG		= match2;
++
++	// Clock Source: PCLK
++	control_value &= ~(1 << TIMER2_CLOCK_SOURCE_BIT_INDEX);
++
++	// UP Count Mode
++	control_value &= ~(1 << TIMER2_UP_DOWN_COUNT_BIT_INDEX);
++
++	// un-mask match1, match2, and overflow interrupt sources
++	mask_value &= ~(0x7 << 3);
++
++	// mask match1, match2 interrupt sources
++	//mask_value |= (0x3 << 3);
++	val=0;
++	if(!match1) val|=0x1;
++	if(!match2) val|=0x2;
++	mask_value |= (val<< 3);
++
++	TIMER_CONTROL_REG = control_value;
++	TIMER_INTERRUPT_MASK_REG = mask_value;
++}
++
++static void str9100_counter_enable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER_CONTROL_REG;
++
++	// enable overflow mode
++	control_value |= (1 << TIMER2_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// enable the timer
++	control_value |= (1 << TIMER2_ENABLE_BIT_INDEX);
++
++	TIMER_CONTROL_REG = control_value;
++}
++
++static void str9100_counter_disable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER_CONTROL_REG;
++
++	// enable overflow mode
++	control_value &= ~(1 << TIMER2_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// enable the timer
++	control_value &= ~(1 << TIMER2_ENABLE_BIT_INDEX);
++
++	TIMER_CONTROL_REG = control_value;
++}
++
++/*
++ * IRQ handler for the timer
++ */
++static irqreturn_t
++str9100_counter_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	// clear counter interrrupt status
++	TIMER_INTERRUPT_STATUS_REG &= ~(1 << TIMER2_OVERFLOW_INTERRUPT_BIT_INDEX);
++	str9100_counter_tick += (1ULL << 32);
++	if(match1){
++		TIMER2_MATCH_VALUE1_REG=TIMER2_COUNTER_REG+match1;
++		TIMER_INTERRUPT_MASK_REG |= (0x1<<3);
++	}
++	if(match2){
++		TIMER2_MATCH_VALUE2_REG=TIMER2_COUNTER_REG+match2;
++		TIMER_INTERRUPT_MASK_REG |= (0x2<<3);
++	}
++	return IRQ_HANDLED;
++}
++
++static struct irqaction str9100_counter_irq = {
++	.name		= "STR9100 Counter Tick",
++	/* scott.patch */
++	.flags		= IRQF_DISABLED | IRQF_TIMER,
++	.handler	= str9100_counter_interrupt,
++};
++
++static int str9100_counter_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
++{
++	return sprintf(page, "str9100_counter_tick: %llu\n", str9100_counter_tick + TIMER2_COUNTER_REG);
++}
++static int
++str9100_counter_write_proc(struct file *file, const char __user *buffer,
++	unsigned long count, void *data)
++{
++	char *str;
++	char *cmd;
++
++	if (count > 0) {
++		str = (char *)buffer,
++		cmd = strsep(&str, "\t \n");
++		if (!cmd) goto err_out;
++		if (strcmp(cmd, "match1") == 0) {
++			u32 addr;
++			u32 vir_addr;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 10);
++			match1=addr;
++
++		} else if (strcmp(cmd, "match2") == 0) {
++			u32 addr;
++			u32 vir_addr;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 10);
++			match2=addr;
++
++
++		} else {
++			goto err_out;
++		}
++	}
++	if(match1){
++		TIMER2_MATCH_VALUE1_REG=TIMER2_COUNTER_REG+match1;
++		TIMER_INTERRUPT_MASK_REG |= (0x1<<3);
++	}
++	if(match2){
++		TIMER2_MATCH_VALUE2_REG=TIMER2_COUNTER_REG+match2;
++		TIMER_INTERRUPT_MASK_REG |= (0x2<<3);
++	}
++
++	return count;
++
++err_out:
++	return -EFAULT;
++}
++
++/*
++ * Set up timer interrupt, and return the current time in seconds.
++ */
++int __init str9100_counter_setup(void)
++{
++	str9100_setup_counter();
++	setup_irq(INTC_TIMER2_BIT_INDEX, &str9100_counter_irq);
++	str9100_counter_enable();
++	str9100_counter_proc_entry = create_proc_entry("str9100/counter", S_IFREG | S_IRUGO, NULL);
++	if (str9100_counter_proc_entry) {
++		str9100_counter_proc_entry->read_proc = str9100_counter_read_proc;
++		str9100_counter_proc_entry->write_proc = str9100_counter_write_proc;
++
++	}
++
++	return 0;
++}
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_debug.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_debug.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_debug.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_debug.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,48 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/types.h>
++#include <asm/hardware.h>
++
++void debug_puts(const char *s)
++{
++	while (*s) {
++		volatile unsigned int status = 0;
++		do {
++			status = _UART_LSR;
++		} while (!((status & THR_EMPTY) == THR_EMPTY));
++
++		_UART_THR = *s;
++
++		if (*s == '\n') {
++			do {
++				status = _UART_LSR;
++			} while (!((status & THR_EMPTY) == THR_EMPTY));
++
++			_UART_THR = '\r';
++
++		}
++		s++;
++	}
++}
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_gpio.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_gpio.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_gpio.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_gpio.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,532 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/miscdevice.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/sched.h>
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/arch/star_gpio.h>
++
++#include <linux/str9100/str9100_gpio.h>
++
++#ifdef CONFIG_STR9100_GPIO_INTERRUPT
++#define MAX_GPIO_LINE		21
++void (*gpio_isr[MAX_GPIO_LINE])(int i);
++#endif
++
++/* 
++ * Read GPIO input data from register
++ */
++int str9100_gpio_in(volatile __u32 *data)
++{
++	*data = GPIO_DATA_IN_REG;
++	return 0;
++}
++
++/* 
++ * Write data to  GPIO output register
++ */
++int str9100_gpio_out(__u32 data)
++{
++	GPIO_DATA_OUT_REG = data;
++	return 0;
++}
++
++/* 
++ * Read GPIO direction Register
++ */
++int str9100_gpio_read_direction(volatile __u32 *data)
++{
++	*data = GPIO_PIN_DIR_REG;
++	return 0;
++}
++
++/* 
++ * Write GPIO direction Register
++ */
++int str9100_gpio_write_direction(__u32 data)
++{
++	GPIO_PIN_DIR_REG = data;
++	return 0;
++}
++
++/* 
++ * Write GPIO set Register
++ */
++int str9100_gpio_dataset(__u32 data)
++{
++	GPIO_DATA_SET_REG = data;
++	return 0;
++}
++
++/* 
++ * Write GPIO clear Register
++ */
++int str9100_gpio_dataclear(__u32 data)
++{
++	GPIO_DATA_CLEAR_REG = data;
++	return 0;
++}
++
++/* Read GPIO Data, but only one bit */
++int str9100_gpio_in_bit(volatile __u32 *data, int bit)
++{
++	u32 temp;
++	if (bit >= 0 && bit <= 20) {
++		str9100_gpio_in(&temp);
++		*data = ((temp >> bit)&0x1);
++	}
++	return 0;
++}
++
++/* Write GPIO Data, but only one bit */
++int str9100_gpio_out_bit(__u32 data, int bit)
++{
++	u32 temp;
++	if (bit >= 0 && bit <= 20) {
++		str9100_gpio_in(&temp);
++		temp &= ~(1 <<bit);
++		temp |= (data &0x1)<< bit;
++		str9100_gpio_out(temp);
++	}
++	return 0;
++
++}
++
++int str9100_gpio_read_direction_bit(volatile __u32 *data, int bit)
++{
++	u32 temp;
++	if (bit >= 0 && bit <= 20) {
++		str9100_gpio_read_direction(&temp);
++		*data = ((temp >> bit)&0x1);
++	}
++	return 0;
++}
++
++int str9100_gpio_write_direction_bit(__u32 data, int bit)
++{
++	u32 temp;
++	if (bit >= 0 && bit <= 20) {
++		str9100_gpio_read_direction(&temp);
++		temp &= ~(1 <<bit);
++		temp |= (data &0x1)<< bit;
++		str9100_gpio_write_direction(temp);
++	}
++	return 0;
++}
++
++int str9100_gpio_dataset_bit(__u32 data, int bit)
++{
++	u32 temp=0;
++	if (bit >= 0 && bit <= 20) {
++		temp |= (data &0x1)<< bit;
++		str9100_gpio_dataset(temp);
++	}
++	return 0;
++}
++
++int str9100_gpio_dataclear_bit(__u32 data, int bit)
++{
++	u32 temp=0;
++	if (bit >= 0 && bit <= 20) {
++		temp |= (data &0x1)<< bit;
++		str9100_gpio_dataclear(temp);
++	}
++	return 0;
++}
++
++#define GEN_GPIO_WRITE_SCRIPT(regname)\
++int str9100_gpio_write_##regname##_bit(volatile __u32 data,int bit) \
++{ \
++	u32 temp=0; \
++	if (bit >= 0 && bit <= 20) { \
++		temp |= ((data &0x1)<< bit); \
++		str9100_gpio_write_##regname(temp); \
++	} \
++	return 0; \
++} 
++//EXPORT_SYMBOL(str9100_gpio_write_##regname_bit);
++
++#define GEN_GPIO_READ_SCRIPT(regname) \
++int str9100_gpio_read_##regname##_bit(volatile __u32 *data,int bit) \
++{ \
++	u32 temp; \
++	if (bit >= 0 && bit <= 20) { \
++		str9100_gpio_read_##regname(&temp); \
++		*data = ((temp >> bit)&0x1); \
++	} \
++	return 0; \
++} 
++//EXPORT_SYMBOL(str9100_gpio_read_##regname_bit);
++
++#ifdef CONFIG_STR9100_GPIO_INTERRUPT
++int str9100_gpio_read_intrenable(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_ENABLE_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrenable);
++
++int str9100_gpio_write_intrenable(__u32 data)
++{
++	GPIO_INTERRUPT_ENABLE_REG = data;
++	return 0;
++}
++GEN_GPIO_WRITE_SCRIPT(intrenable);
++
++int str9100_gpio_read_intrrawstate(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_RAW_STATE_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrrawstate);
++
++int str9100_gpio_read_intrmaskedstatus(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_MASKED_STATE_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrmaskedstatus);
++
++int str9100_gpio_read_intrmask(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_MASK_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrmask);
++
++int str9100_gpio_write_intrmask(__u32 data)
++{
++	GPIO_INTERRUPT_MASK_REG = data;
++	return 0;
++}
++GEN_GPIO_WRITE_SCRIPT(intrmask);
++
++int str9100_gpio_read_intrclear(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_CLEAR_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrclear);
++
++int str9100_gpio_write_intrclear(__u32 data)
++{
++	GPIO_INTERRUPT_CLEAR_REG = data;
++	return 0;
++}
++GEN_GPIO_WRITE_SCRIPT(intrclear);
++
++int str9100_gpio_read_intrtrigger(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_TRIGGER_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrtrigger);
++
++int str9100_gpio_write_intrtrigger(__u32 data)
++{
++	GPIO_INTERRUPT_TRIGGER_REG = data;
++	return 0;
++}
++GEN_GPIO_WRITE_SCRIPT(intrtrigger);
++
++int str9100_gpio_read_intrboth(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_BOTH_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrboth);
++
++int str9100_gpio_write_intrboth(__u32 data)
++{
++	GPIO_INTERRUPT_BOTH_REG = data;
++	return 0;
++}
++GEN_GPIO_WRITE_SCRIPT(intrboth);
++
++int str9100_gpio_read_intrriseneg(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_RISE_NEG_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrriseneg);
++
++int str9100_gpio_write_intrriseneg(__u32 data)
++{
++	GPIO_INTERRUPT_RISE_NEG_REG = data;
++	return 0;
++}
++GEN_GPIO_WRITE_SCRIPT(intrriseneg);
++
++#endif
++
++#if 0
++EXPORT_SYMBOL(str9100_gpio_in);
++EXPORT_SYMBOL(str9100_gpio_out);
++EXPORT_SYMBOL(str9100_gpio_in_bit);
++EXPORT_SYMBOL(str9100_gpio_out_bit);
++EXPORT_SYMBOL(str9100_gpio_read_direction);
++EXPORT_SYMBOL(str9100_gpio_write_direction);
++EXPORT_SYMBOL(str9100_gpio_read_direction_bit);
++EXPORT_SYMBOL(str9100_gpio_write_direction_bit);
++EXPORT_SYMBOL(str9100_gpio_dataset);
++EXPORT_SYMBOL(str9100_gpio_dataclear);
++EXPORT_SYMBOL(str9100_gpio_dataset_bit);
++EXPORT_SYMBOL(str9100_gpio_dataclear_bit);
++
++#ifdef CONFIG_STR9100_GPIO_INTERRUPT
++EXPORT_SYMBOL(str9100_gpio_read_intrenable);
++EXPORT_SYMBOL(str9100_gpio_write_intrenable);
++EXPORT_SYMBOL(str9100_gpio_read_intrrawstate);
++EXPORT_SYMBOL(str9100_gpio_read_intrmaskedstatus);
++EXPORT_SYMBOL(str9100_gpio_read_intrmask);
++EXPORT_SYMBOL(str9100_gpio_write_intrmask);
++EXPORT_SYMBOL(str9100_gpio_read_intrclear);
++EXPORT_SYMBOL(str9100_gpio_write_intrclear);
++EXPORT_SYMBOL(str9100_gpio_read_intrtrigger);
++EXPORT_SYMBOL(str9100_gpio_write_intrtrigger);
++EXPORT_SYMBOL(str9100_gpio_read_intrboth);
++EXPORT_SYMBOL(str9100_gpio_write_intrboth);
++EXPORT_SYMBOL(str9100_gpio_read_intrriseneg);
++EXPORT_SYMBOL(str9100_gpio_write_intrriseneg);
++#endif
++#endif
++
++static int str9100_gpio_proc(char *page, char **start,  off_t off, int count, int *eof, void *data)
++{
++	u32 temp;
++	int num=0;
++
++	str9100_gpio_in(&temp);
++	num += sprintf(page+num, "GPIO IN                : %08x \n", temp);
++
++	str9100_gpio_read_direction(&temp);
++	num += sprintf(page+num, "GPIO Direction         : %08x \n", temp);
++
++#ifdef CONFIG_STR9100_GPIO_INTERRUPT
++	str9100_gpio_read_intrenable(&temp);
++	num += sprintf(page+num, "GPIO Interrupt Enable  : %08x \n", temp);
++
++	str9100_gpio_read_intrrawstate(&temp);
++	num += sprintf(page+num, "GPIO Interrupt Raw     : %08x \n", temp);
++
++	str9100_gpio_read_intrtrigger(&temp);
++	num += sprintf(page+num, "GPIO Interrupt Trigger : %08x \n", temp);
++
++	str9100_gpio_read_intrboth(&temp);
++	num += sprintf(page+num, "GPIO Interrupt Both    : %08x \n", temp);
++
++	str9100_gpio_read_intrriseneg(&temp);
++	num += sprintf(page+num, "GPIO Interrupt RiseNeg : %08x \n", temp);
++
++	str9100_gpio_read_intrmask(&temp);
++	num += sprintf(page+num, "GPIO Interrupt MASKED  : %08x \n", temp);
++
++	str9100_gpio_read_intrmaskedstatus(&temp);
++	num += sprintf(page+num, "GPIO Interrupt MASKEDST: %08x \n", temp);
++#endif	
++
++	return num;
++}
++
++#ifdef CONFIG_STR9100_GPIO_INTERRUPT
++static void str9100_gpio_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	int i;
++	u32 gpio_intr;
++
++	// Clean System irq status
++	INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++	INTC_INTERRUPT_MASK_REG |= (0x1 << INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++
++	str9100_gpio_read_intrrawstate(&gpio_intr);
++	//printk("GPIO INTERRUPT : %08x \n",gpio_intr);
++
++	for (i = 0; i < MAX_GPIO_LINE; i++) {
++		if ((gpio_intr &0x1) == 0x1) {
++			if (gpio_isr[i] != NULL) {
++				gpio_isr[i](i);
++			}
++		}
++		gpio_intr = gpio_intr >> 1;
++	}
++	/* Clear All Interrupt Status */
++	str9100_gpio_write_intrclear(0x1FFFFF);
++	/* Unmask Intc Interrupt Status */
++	INTC_INTERRUPT_MASK_REG &= ~(0x1 << INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++}
++
++/*  
++ * Setup GPIO for Edge Triggle Interrupt mode 
++ */
++void str9100_gpio_set_edgeintr(void (*funcptr)(int),int trig_both,int trig_rising, int gpio_pin)
++{
++	u32 intrtmp;
++	
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIO_LINE) {
++		str9100_gpio_write_direction_bit(PIN_INPUT,gpio_pin);
++
++		/* Set Triggle Level */
++		str9100_gpio_read_intrtrigger(&intrtmp);
++		intrtmp &= ~(0x1 << gpio_pin);
++		intrtmp |= (PIN_TRIG_EDGE << gpio_pin);
++		str9100_gpio_write_intrtrigger(intrtmp);
++
++		/* Set Triggle Both */
++		str9100_gpio_read_intrboth(&intrtmp);
++		intrtmp &= ~(0x1 << gpio_pin);
++		intrtmp |= (trig_both << gpio_pin);
++		str9100_gpio_write_intrboth(intrtmp);
++
++		/* Set Triggle Rising/Falling */
++		str9100_gpio_read_intrriseneg(&intrtmp);
++		intrtmp &= ~(0x1 << gpio_pin);
++		intrtmp |= (trig_rising << gpio_pin);
++		str9100_gpio_write_intrriseneg(intrtmp);
++
++		gpio_isr[gpio_pin] = funcptr;
++
++		// Enable Interrupt
++		str9100_gpio_read_intrenable(&intrtmp);
++		intrtmp |= (0x1 << gpio_pin);
++		str9100_gpio_write_intrenable(intrtmp);
++	}
++}
++/*  
++ * Clear GPIO Triggle Interrupt
++ */
++void str9100_gpio_clear_intr(int gpio_pin)
++{
++	u32 intrtmp;
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIO_LINE) {
++		gpio_isr[gpio_pin] = NULL;
++		// Disable Interrupt
++		str9100_gpio_read_intrenable(&intrtmp);
++		intrtmp &= ~( 0x1 << gpio_pin);
++		str9100_gpio_write_intrenable(intrtmp);
++	}
++}
++
++/*  
++ * Setup GPIO for LEVEL Triggle Interrupt mode 
++ */
++void str9100_gpio_set_levelintr(void (*funcptr)(int),int trig_level, int gpio_pin)
++{
++	u32 intrtmp;
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIO_LINE) {
++		str9100_gpio_write_direction_bit(PIN_INPUT,gpio_pin);
++		/* Set Triggle Level */
++		str9100_gpio_read_intrtrigger(&intrtmp);
++		intrtmp &= ~(0x1 << gpio_pin);
++		intrtmp |= (PIN_TRIG_LEVEL << gpio_pin);
++		str9100_gpio_write_intrtrigger(intrtmp);
++
++		/* Set Triggle High/Low */
++		str9100_gpio_read_intrriseneg(&intrtmp);
++		intrtmp &= ~(0x1 << gpio_pin);
++		intrtmp |= (trig_level << gpio_pin);
++		str9100_gpio_write_intrriseneg(intrtmp);
++
++		gpio_isr[gpio_pin] = funcptr;
++
++		// Enable Interrupt
++		str9100_gpio_read_intrenable(&intrtmp);
++		intrtmp |= (0x1 << gpio_pin);
++		str9100_gpio_write_intrenable(intrtmp);
++	}
++}
++EXPORT_SYMBOL(str9100_gpio_set_edgeintr);
++EXPORT_SYMBOL(str9100_gpio_clear_intr);
++EXPORT_SYMBOL(str9100_gpio_set_levelintr);
++
++/*  
++ * Display GPIO information at /proc/str9100/gpio
++ */
++
++#ifdef STR9100_GPIO_INTERRUPT_TEST
++void str9100_gpio_intr_test(int i)
++{
++	printk("GPIO Interrupt Service Single Active : %d \n",i);
++}
++#endif
++
++#endif
++static struct proc_dir_entry *proc_str9100_gpio;
++int __init str9100_gpio_init(void)
++{
++#ifdef CONFIG_STR9100_GPIO_INTERRUPT
++	u32 i, ret;
++#endif
++#ifdef STR9100_GPIO_INTERRUPT_TEST
++	/* test script */
++	u32 temp;
++	str9100_gpio_read_direction(&temp);
++	printk("direction: %08X\n",temp);
++	str9100_gpio_write_direction_bit(PIN_OUTPUT,15);
++	str9100_gpio_read_direction(&temp);
++	printk("direction: %08X\n",temp);
++	str9100_gpio_in(&temp);
++	printk("data: %08X\n",temp);
++#endif
++
++	proc_str9100_gpio = create_proc_read_entry("str9100/gpio", 0, NULL, str9100_gpio_proc, NULL) ;
++
++#ifdef CONFIG_STR9100_GPIO_INTERRUPT
++	for (i = 0; i < MAX_GPIO_LINE; i++) {
++		gpio_isr[i] = NULL;
++	}
++	/* Clear All Interrupt Status */
++	str9100_gpio_write_intrclear(0x1FFFFF);
++	str9100_set_interrupt_trigger(INTC_GPIO_EXTERNAL_INT_BIT_INDEX, INTC_EDGE_TRIGGER, INTC_RISING_EDGE);
++	ret = request_irq(INTC_GPIO_EXTERNAL_INT_BIT_INDEX, str9100_gpio_irq_handler, 0, "str9100_gpio", 0);
++	if (ret < 0) {
++		printk("request_irq fail : %d \n", ret);
++		return 0;
++	} else {
++		printk("GPIO interrupt handler install ok. \n");
++	}
++#endif
++#ifdef STR9100_GPIO_INTERRUPT_TEST
++	str9100_gpio_set_edgeintr(&str9100_gpio_intr_test,PIN_TRIG_SINGLE,PIN_TRIG_RISING,12);
++#endif
++
++	return 0;
++}	
++
++void __exit str9100_gpio_exit(void)
++{
++	free_irq(INTC_GPIO_EXTERNAL_INT_BIT_INDEX,0);
++}
++
++module_init(str9100_gpio_init);
++module_exit(str9100_gpio_exit);
++
++MODULE_LICENSE("GPL");
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_intc.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_intc.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_intc.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_intc.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,193 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++
++#include <asm/hardware.h>
++#include <asm/mach/irq.h>
++#include <asm/irq.h>
++
++#define INTC_TRIGGER_UNKNOWN -1
++
++typedef struct
++{
++	int	mode;
++	int	level;
++} intc_trigger_t;
++
++static intc_trigger_t intc_trigger_table[] =
++{
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 0
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 1
++	{ INTC_EDGE_TRIGGER,	INTC_FALLING_EDGE	},	// 2
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 3
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 4
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 5
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 6
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 7
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 8
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 9
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 10
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 11
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 12
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 13
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 14
++	{ INTC_EDGE_TRIGGER,	INTC_FALLING_EDGE	},	// 15
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 16
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 17
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 18
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 19
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 20
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 21
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 22
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 23
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 24
++};
++
++/*
++ * Configure interrupt trigger mode to be level trigger or edge trigger
++ */
++static inline void str9100_set_irq_mode(unsigned int irq, unsigned int mode)
++{
++	unsigned int val;
++
++	if (irq < 0 || irq > NR_IRQS) {
++		return;
++	}
++
++	if ((mode != INTC_LEVEL_TRIGGER) &&
++		(mode != INTC_EDGE_TRIGGER)) {
++		return;
++	}
++
++	val = INTC_INTERRUPT_TRIGGER_MODE_REG;
++
++	if (mode == INTC_LEVEL_TRIGGER) {
++		if (val & (1UL << irq)) {
++			val &= ~(1UL << irq);
++			INTC_INTERRUPT_TRIGGER_MODE_REG = val;
++		}
++	} else {
++		if (!(val & (1UL << irq))) {
++			val |= (1UL << irq);
++			INTC_INTERRUPT_TRIGGER_MODE_REG = val;
++		}
++	}
++}	
++
++/*
++ * Configure interrupt trigger level to be Active High/Low or Rising/Falling Edge
++ */
++static inline void str9100_set_irq_level(unsigned int irq, unsigned int level)
++{
++	unsigned int val;
++
++	if (irq < 0 || irq > NR_IRQS) {
++		return;
++	}
++
++	if ((level != INTC_ACTIVE_HIGH) &&
++		(level != INTC_ACTIVE_LOW) &&
++		(level != INTC_RISING_EDGE) &&
++		(level != INTC_FALLING_EDGE)) {
++		return;
++	}
++
++	val = INTC_INTERRUPT_TRIGGER_LEVEL_REG;
++
++	if ((level == INTC_ACTIVE_HIGH) ||
++		(level == INTC_RISING_EDGE)) {
++		if (val & (1UL << irq)) {
++			val &= ~(1UL << irq);
++			INTC_INTERRUPT_TRIGGER_LEVEL_REG = val;
++		}
++	} else {
++		if (!(val & (1UL << irq))) {
++			val |= (1UL << irq);
++			INTC_INTERRUPT_TRIGGER_LEVEL_REG = val;
++		}
++	}
++}
++
++/*
++ * Configure interrupt trigger mode and trigger level
++ */
++void str9100_set_interrupt_trigger(unsigned int irq, unsigned int mode, unsigned int level)
++{
++	str9100_set_irq_mode(irq, mode);
++	str9100_set_irq_level(irq, level);
++}
++EXPORT_SYMBOL(str9100_set_interrupt_trigger);
++
++/*
++ * Mask/Disable this interrupt source
++ */
++static void str9100_mask_irq(unsigned int irq)
++{
++	// Mask/Disable this interrupt source
++	INTC_INTERRUPT_MASK_REG |= (1UL << irq);
++}
++
++/*
++ * Un-Mask/Enable this interrupt source
++ */
++static void str9100_unmask_irq(unsigned int irq)
++{
++	// Clear interrupt status of the interrupt source which is edge-triggered
++	INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG |= (1UL << irq);
++
++	// Mask/Disable this interrupt source
++	INTC_INTERRUPT_MASK_REG &= ~(1UL << irq);
++}
++
++static struct irq_chip str9100_irqchip = {
++	.ack	= str9100_mask_irq,
++	.mask	= str9100_mask_irq,
++	.unmask	= str9100_unmask_irq,
++};
++
++void __init str9100_init_irq(void)
++{
++	int i;
++
++	INTC_INTERRUPT_MASK_REG = 0xFFFFFFFF;
++	INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG = 0xFFFFFFFF;	
++	INTC_FIQ_MODE_SELECT_REG = 0x0;
++
++	for (i = 0; i < NR_IRQS; i++) {
++		if (intc_trigger_table[i].mode != INTC_TRIGGER_UNKNOWN) {
++			str9100_set_irq_mode(i, intc_trigger_table[i].mode);
++			str9100_set_irq_level(i, intc_trigger_table[i].level);
++		}
++	}
++	
++	for (i = 0; i < NR_IRQS;  i++) {
++		set_irq_chip(i, &str9100_irqchip);
++		/* scott.patch */
++		set_irq_handler(i, handle_level_irq);
++		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
++	}
++}
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_misc.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_misc.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_misc.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_misc.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,249 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/proc_fs.h>
++#include <asm/mach/map.h>
++#include <asm/hardware.h>
++
++// enable I-Scratchpad
++int str9100_enable_ispad(u32 base_addr)
++{
++	u32 ispad_config = 0;
++	u32 flush_ispad = 0;
++	u32 ispad_size = 4; // 8K on STR9100
++	u32 cp15 = 1, cp15_off = 0;
++
++	// Configure Base
++	ispad_config |= (base_addr & 0xfffffc00);
++
++	// Configure Size
++	ispad_config &= ~(0xf << 2);
++	ispad_config |= ((ispad_size & 0xf) << 2) | (0x1 << 2);
++
++	// Enable
++	ispad_config |= 0x1;
++
++	// 1. set cp15, cr1-1(ECR) register value to 0x1
++	// 2. set up the base and size configuration
++	// 3. Invalidate IScratchpad All(flushed ISpad)
++	// 4. clear cp15, cr1-1(ECR) register value to 0x0
++	__asm__ __volatile__ (
++	"mcr p15,0,%0,c1,c1,0\n\t"
++	"mcr p15,0,%1,c9,c1,1\n\t"
++	"mcr p15,0,%2,c7,c5,5\n\t"
++	"mcr p15,0,%3,c1,c1,0\n\t"
++	"nop\n\t"
++	"nop\n\t"
++	"nop\n\t"
++	"nop\n\t"
++	"nop\n\t"
++	:
++	: "r"(cp15), "r"(ispad_config), "r"(flush_ispad), "r"(cp15_off));
++	
++	return 0;
++}
++
++static struct map_desc str9100_map_desc[64];
++static int str9100_map_desc_count;
++#define REG_DEBUG_CMD_BUFFER_SIZE	128
++#define REG_DEBUG_RESULT_BUFFER_SIZE	256
++static struct proc_dir_entry *star_reg_debug_proc_entry;
++static char str9100_reg_debug_cmd_buf[REG_DEBUG_CMD_BUFFER_SIZE];
++static char str9100_reg_debug_result_buf[REG_DEBUG_RESULT_BUFFER_SIZE];
++
++struct proc_dir_entry *str9100_proc_dir;
++EXPORT_SYMBOL(str9100_proc_dir);
++
++void str9100_register_map_desc(struct map_desc *map, int count)
++{
++	if (count) {
++		if (str9100_map_desc) {
++			int i;
++			for (i = 0; i < count; i++) {
++				str9100_map_desc[i].virtual = map->virtual;
++				str9100_map_desc[i].pfn = map->pfn;
++				str9100_map_desc[i].length = map->length;
++				str9100_map_desc[i].type = map->type;
++				map++;
++			}
++			str9100_map_desc_count = count;
++		}
++	}
++}
++
++u32 str9100_query_map_desc_by_phy(u32 addr)
++{
++	struct map_desc *map;
++	int i;
++	u32 ret_addr = 0;
++	for (i = 0; i < str9100_map_desc_count; i++) {
++		map = &str9100_map_desc[i];
++		if (addr >= (map->pfn << PAGE_SHIFT) && addr < ((map->pfn << PAGE_SHIFT) + map->length)) {
++			ret_addr = map->virtual + (addr - (map->pfn << PAGE_SHIFT));
++			break;
++		}
++	}
++
++	return ret_addr;
++}
++
++u32 str9100_query_map_desc_by_vir(u32 addr)
++{
++	struct map_desc *map;
++	int i;
++	u32 ret_addr = 0;
++	for (i = 0; i < str9100_map_desc_count; i++) {
++		map = &str9100_map_desc[i];
++		if (addr >= map->virtual && addr < (map->virtual + map->length)) {
++			ret_addr = (map->pfn << PAGE_SHIFT) + (addr - map->virtual);
++			break;
++		}
++	}
++
++	return ret_addr;
++}
++
++static int star_reg_debug_read_proc(char *buffer, char **start, off_t offset,
++	int length, int *eof, void *data)
++{
++	int count;
++	int num = 0;
++
++	if (str9100_reg_debug_cmd_buf[0]) {
++		count = strlen(str9100_reg_debug_cmd_buf);
++		sprintf(buffer, str9100_reg_debug_cmd_buf, count);
++		num += count;
++	}
++	if (str9100_reg_debug_result_buf[0]) {
++		count = strlen(str9100_reg_debug_result_buf);
++		sprintf(buffer + num, str9100_reg_debug_result_buf, count);
++		num += count;
++	}
++
++	return num;
++}
++
++static int
++star_reg_debug_write_proc(struct file *file, const char __user *buffer,
++	unsigned long count, void *data)
++{
++	char *str;
++	char *cmd;
++
++	if (count > 0) {
++		str = (char *)buffer,
++		cmd = strsep(&str, "\t \n");
++		if (!cmd) goto err_out;
++		if (strcmp(cmd, "dump") == 0) {
++			u32 addr;
++			u32 vir_addr;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 16);
++			if (addr & 0x3) goto err_out;
++			vir_addr = str9100_query_map_desc_by_phy(addr);
++			sprintf(str9100_reg_debug_cmd_buf,
++				"dump 0x%08x\n",
++				addr);
++			if (!vir_addr) goto err_out;
++			sprintf(str9100_reg_debug_result_buf,
++				"physical addr: 0x%08x content: 0x%08x\n",
++				addr,
++				*(volatile unsigned int __force *)(vir_addr));
++		} else if (strcmp(cmd, "write") == 0) {
++			u32 addr;
++			u32 vir_addr;
++			u32 data;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 16);
++			arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			data = simple_strtoul(arg, &arg, 16);
++			if (addr & 0x3) goto err_out;
++			vir_addr = str9100_query_map_desc_by_phy(addr);
++			if (!vir_addr) goto err_out;
++			*(volatile unsigned int __force *)(vir_addr) = data;
++			sprintf(str9100_reg_debug_cmd_buf,
++				"write 0x%08x 0x%08x\n",
++				addr, data);
++			sprintf(str9100_reg_debug_result_buf,
++				"physical addr: 0x%08x content: 0x%08x\n",
++				addr,
++				*(volatile unsigned int __force *)(vir_addr));
++		} else {
++			goto err_out;
++		}
++	}
++
++	return count;
++
++err_out:
++	return -EFAULT;
++}
++
++static int __init star_reg_debug_proc_init(void)
++{
++	star_reg_debug_proc_entry = create_proc_entry("str9100/reg_debug", S_IFREG | S_IRUGO, NULL);
++	if (star_reg_debug_proc_entry) {
++		star_reg_debug_proc_entry->read_proc = star_reg_debug_read_proc;
++		star_reg_debug_proc_entry->write_proc = star_reg_debug_write_proc;
++	}
++
++	return 0;
++}
++
++static int __init str9100_proc_dir_create(void)
++{
++	str9100_proc_dir = proc_mkdir("str9100", NULL);
++	if (str9100_proc_dir) {
++		str9100_proc_dir->owner = THIS_MODULE;
++	} else {
++		printk("Error: cannot crete str9100 proc dir entry at /proc/str9100\n");
++		return -EINVAL;
++	}
++
++	if (str9100_map_desc_count) {
++		(void)star_reg_debug_proc_init();
++	}
++
++	return 0;
++}
++
++extern int __init str9100_counter_setup(void);
++static int __init str9100_misc_init(void)
++{
++	str9100_proc_dir_create();
++	str9100_counter_setup();
++	return 0;
++}
++
++module_init(str9100_misc_init);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Star Semi Corporation");
++MODULE_DESCRIPTION("STR9100 MISC");
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_pci.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_pci.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_pci.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_pci.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,331 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/ptrace.h>
++#include <linux/slab.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/init.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++#include <asm/mach/pci.h>
++
++#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | ((bus) << 16) | ((device_fn) << 8) | ((where) & ~3))
++
++static struct pci_dev *pci_bridge = NULL;
++static u32 pci_config_addr;				// PCI configuration register address port
++static u32 pci_config_data;				// PCI configuration register data port
++u32 str9100_pci_irqs[4] = {0, INTC_PCI_INTA_BIT_INDEX, INTC_PCI_INTB_BIT_INDEX, 0};
++
++static int str9100_pci_read_config(struct pci_bus *bus,
++	unsigned int devfn, int where, int size, u32 *val)
++{
++	u32 v = 0;
++	u32 shift;
++	unsigned long flags;
++
++	switch (size) {
++	case 1:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		local_irq_restore(flags);
++		v = (v >> shift) & 0xff;
++		break;
++
++	case 2:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		local_irq_restore(flags);
++		v = (v >> shift) & 0xffff;
++
++		break;
++
++	case 4:
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		local_irq_restore(flags);
++		break;
++	}
++
++	*val = v;
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static int str9100_pci_write_config(struct pci_bus *bus,
++	unsigned int devfn, int where, int size, u32 val)
++{
++	u32 v;
++	u32 shift;
++	unsigned long flags;
++
++	switch (size) {
++	case 1:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		v = (v & ~(0xff << shift)) | (val << shift);
++		__raw_writel(v, pci_config_data);
++		local_irq_restore(flags);
++		break;
++
++	case 2:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		v = (v & ~(0xffff << shift)) | (val << shift);
++		__raw_writel(v, pci_config_data);
++		local_irq_restore(flags);
++		break;
++
++	case 4:
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		__raw_writel(val, pci_config_data);
++		local_irq_restore(flags);
++		break;
++	}
++
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops str9100_pci_ops = {
++	.read	= str9100_pci_read_config,
++	.write	= str9100_pci_write_config,
++};
++
++static struct resource str9100_pci_io = {
++	.name	= "PCI I/O space",
++	.start	= PCI_IO_SPACE_START,
++	.end	= PCI_IO_SPACE_END, //albert : 20040714
++	.flags	= IORESOURCE_IO,
++};
++
++static struct resource str9100_pci_nprefetch_mem = {
++	.name	= "PCI non-prefetchable",
++	.start	= PCI_NPREFETCH_MEMORY_SPACE_START,
++	.end	= PCI_NPREFETCH_MEMORY_SPACE_END,
++	.flags	= IORESOURCE_MEM,
++};
++
++static struct resource str9100_pci_prefetch_mem = {
++	.name	= "PCI prefetchable",
++	.start	= PCI_PREFETCH_MEMORY_SPACE_START,
++	.end	= PCI_PREFETCH_MEMORY_SPACE_END,
++	.flags	= IORESOURCE_MEM | IORESOURCE_PREFETCH,
++};
++
++static int __init str9100_pci_setup_resources(struct resource **resource)
++{
++	int ret = -1;
++
++	ret = request_resource(&iomem_resource, &str9100_pci_io);
++	if (ret) {
++		printk(KERN_ERR "PCI: unable to allocate I/O "
++		       "memory region (%d)\n", ret);
++		goto out;
++	}
++	ret = request_resource(&iomem_resource, &str9100_pci_nprefetch_mem);
++	if (ret) {
++		printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
++		       "memory region (%d)\n", ret);
++		goto release_io;
++	}
++	ret = request_resource(&iomem_resource, &str9100_pci_prefetch_mem);
++	if (ret) {
++		printk(KERN_ERR "PCI: unable to allocate prefetchable "
++		       "memory region (%d)\n", ret);
++		goto release_nprefetch_mem;
++	}
++
++	/*
++	 * bus->resource[0] is the IO resource for this bus
++	 * bus->resource[1] is the mem resource for this bus
++	 * bus->resource[2] is the prefetch mem resource for this bus
++	 */
++	resource[0] = &str9100_pci_io;
++	resource[1] = &str9100_pci_nprefetch_mem;
++	resource[2] = &str9100_pci_prefetch_mem;
++
++	ret = 0;
++
++	goto out;
++
++release_nprefetch_mem:
++	release_resource(&str9100_pci_nprefetch_mem);
++release_io:
++	release_resource(&str9100_pci_io);
++out:
++	return ret;
++}
++
++static irqreturn_t PCI_AHB2PCIB_ISR(int irq, void *dev_id, struct pt_regs * regs)
++{
++	u32 status;
++
++	//disable_irq(INTC_PCI_AHB2BRIDGE_BIT_INDEX);
++	pci_read_config_dword(pci_bridge, PCI_COMMAND, &status);
++	printk("AHB to bridge interrupt status: 0x%x\n", status);
++	pci_write_config_dword(pci_bridge, PCI_COMMAND, status);
++	//enable_irq(INTC_PCI_AHB2BRIDGE_BIT_INDEX);
++
++	return IRQ_HANDLED;
++}
++
++static irqreturn_t PCI_BROKEN_ISR(int irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 status;
++
++	status = MISC_PCI_BROKEN_STATUS_REG & 0x1f;
++	printk("PCI BROKEN interrupt status: 0x%x\n", status);
++	MISC_PCI_BROKEN_STATUS_REG = status;
++
++	return IRQ_HANDLED;
++}
++
++int __init str9100_pci_setup(int nr, struct pci_sys_data *sys)
++{
++	if (nr != 0) {
++		return 0;
++	}
++
++	if (str9100_pci_setup_resources(sys->resource)) {
++		BUG();
++	}
++
++	return 1;
++}
++
++struct pci_bus *str9100_pci_scan_bus(int nr, struct pci_sys_data *sys)
++{
++	return pci_scan_bus(sys->busnr, &str9100_pci_ops, sys);
++}
++
++void __init str9100_pci_preinit(void)
++{
++	pci_config_addr = SYSVA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR + PCI_BRIDGE_CONFIG_ADDR_REG_OFFSET;
++	pci_config_data = SYSVA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR + PCI_BRIDGE_CONFIG_DATA_REG_OFFSET;
++
++#if defined(CONFIG_STAR9100_PCI66M)
++	printk("PCI clock at 66M\n");
++	HAL_PWRMGT_ENABLE_PCI_BRIDGE_66MM();
++#elif defined(CONFIG_STAR9100_PCI33M)
++	printk("PCI clock at 33M\n");
++	HAL_PWRMGT_ENABLE_PCI_BRIDGE_33M();
++#else
++	printk("PCI clock at 33M\n");
++	HAL_PWRMGT_ENABLE_PCI_BRIDGE_33M();
++#endif
++}
++
++void __init str9100_pci_postinit(void)
++{
++	pci_bridge = pci_get_device(PCIB_VENDOR_ID, PCIB_DEVICE_ID, NULL);
++	if (pci_bridge == NULL) {
++		printk("PCI Bridge not found\n");
++		return;
++	} else {
++		printk("PCI Bridge found\n");
++	}
++
++	/* scott.patch */
++	request_irq(INTC_PCI_AHB2BRIDGE_BIT_INDEX, PCI_AHB2PCIB_ISR, IRQF_DISABLED, "pci bridge", pci_bridge);
++
++	MISC_PCI_ARBITER_INTERRUPT_MASK_REG &= ~0x1f;
++
++	/* scott.patch */
++	request_irq(INTC_PCI_ARBITOR_BIT_INDEX, PCI_BROKEN_ISR, IRQF_DISABLED, "pci broken", pci_bridge);
++
++	pci_write_config_dword(pci_bridge, PCI_BASE_ADDRESS_0, 0x0); // = 0x0, can NOT use 0x20000000
++	pci_write_config_dword(pci_bridge, PCI_BASE_ADDRESS_1, 0x0); // = 0x0, can NOT use 0x20000000
++
++	// if we enable pci on u-boot
++	// the pci_enable_device will complain with resource collisions
++	// use this to fixup
++	{
++		int i;
++		struct resource *r;
++
++		for (i = 0; i < 6; i++) {
++			r = pci_bridge->resource + i;
++			r->start = 0;
++			r->end = 0;
++		}
++	}
++
++	pci_enable_device(pci_bridge);
++	pci_set_master(pci_bridge);
++}
++
++/*
++ * map the specified device/slot/pin to an IRQ.   Different backplanes may need to modify this.
++ */
++static int __init str9100_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
++{
++	int irq;
++
++	/* slot,  pin,	irq
++	 * 0      1     0
++	 * 1      1     5
++	 * 2      1     6
++	 * 3      1     0
++	 */
++	irq = str9100_pci_irqs[((slot + pin - 1) & 3)];
++
++	printk("PCI map irq: %02x:%02x.%02x slot %d, pin %d, irq: %d\n",
++		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
++		slot, pin, irq);
++
++	return irq;
++}
++
++static struct hw_pci str9100_pci __initdata = {
++	.swizzle		= pci_std_swizzle,
++	.map_irq		= str9100_pci_map_irq,
++	.nr_controllers		= 1,
++	.setup			= str9100_pci_setup,
++	.scan			= str9100_pci_scan_bus,
++	.preinit		= str9100_pci_preinit,
++	.postinit		= str9100_pci_postinit,
++};
++
++static int __init str9100_pci_init(void)
++{
++	pci_common_init(&str9100_pci);
++	return 0;
++}
++
++subsys_initcall(str9100_pci_init);
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_rtc.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_rtc.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_rtc.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_rtc.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,493 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/miscdevice.h>
++#include <linux/ioport.h>
++#include <linux/fcntl.h>
++#include <linux/init.h>
++#include <linux/poll.h>
++#include <linux/proc_fs.h>
++#include <linux/spinlock.h>
++#include <linux/sysctl.h>
++#include <linux/rtc.h>
++#include <linux/interrupt.h>
++
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/system.h>
++
++#include <asm/arch/star_rtc.h>
++#include <asm/arch/star_intc.h>
++
++#define STR9100_RTC_DATE        "20060628"
++#define STR9100_RTC_VERSION     "2.0.0"
++#define DEVICE_NAME             "rtc"
++#define SECS_PER_HOUR           (60 * 60)
++#define SECS_PER_DAY            (SECS_PER_HOUR * 24)
++#define TM_YEAR_BASE            1900
++#define EPOCH_YEAR              1970
++#define RTC_INTR_ALARM		0x20
++
++extern spinlock_t rtc_lock;
++
++static int rtc_busy = 0;
++static unsigned long epoch = 1900;
++static unsigned int  rtc_interrupt_flag = 0;
++static time_t local_rtc_offset, set_rtc_offset, current_rtc_time;
++static DECLARE_WAIT_QUEUE_HEAD(str9100_rtc_wait);
++
++# define __isleap(year) ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
++
++static const unsigned char days_in_mo[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
++                                                                                
++static const unsigned short int __mon_yday[2][13] =
++{
++    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
++    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
++};
++
++static int offtime (const time_t *t, long int offset, struct rtc_time *tp)
++{
++    long int days, rem, y;
++    const unsigned short int *ip;
++				                                                                                
++    days = *t / SECS_PER_DAY;
++    rem = *t % SECS_PER_DAY;
++    rem += offset;
++    while (rem < 0)
++    {
++         rem += SECS_PER_DAY;
++   	 --days;
++    }
++    while (rem >= SECS_PER_DAY)
++    {
++         rem -= SECS_PER_DAY;
++  	 ++days;
++    }
++    tp->tm_hour = rem / SECS_PER_HOUR;
++    rem %= SECS_PER_HOUR;
++    tp->tm_min = rem / 60;
++    tp->tm_sec = rem % 60;
++    tp->tm_wday = (4 + days) % 7;
++    if (tp->tm_wday < 0)
++      tp->tm_wday += 7;
++    y = 1970;
++#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
++#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
++    while (days < 0 || days >= (__isleap (y) ? 366 : 365))
++    {
++   	 long int yg = y + days / 365 - (days % 365 < 0);  
++   	 days -= ((yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1)- LEAPS_THRU_END_OF (y - 1));
++   	 y = yg;
++    }
++    tp->tm_year = y - 1900;
++    if (tp->tm_year != y - 1900)
++      return 0;
++    tp->tm_yday = days;
++    ip = __mon_yday[__isleap(y)];
++    for (y = 11; days < (long int) ip[y]; --y)
++       continue;
++    days -= ip[y];
++    tp->tm_mon = y;
++    tp->tm_mday = days + 1;
++    return 1;
++}
++
++static time_t ydhms_tm_diff (int year, int yday, int hour, int min, int sec, const struct rtc_time *tp)
++{
++    if (!tp) return 1;
++    else {
++      int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
++      int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
++      int a100 = a4 / 25 - (a4 % 25 < 0);
++      int b100 = b4 / 25 - (b4 % 25 < 0);
++      int a400 = a100 >> 2;
++      int b400 = b100 >> 2;
++      int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
++      time_t years = year - (time_t) tp->tm_year;
++      time_t days = (365 * years + intervening_leap_days + (yday - tp->tm_yday));
++      return (60 * (60 * (24 * days+(hour - tp->tm_hour))+(min - tp->tm_min))+(sec - tp->tm_sec));
++    }
++}
++
++static time_t _mktime(struct rtc_time *tp, time_t *offset)
++{
++    time_t t;
++    struct rtc_time tm;
++    int sec = tp->tm_sec;
++    int min = tp->tm_min;
++    int hour = tp->tm_hour;
++    int mday = tp->tm_mday;
++    int mon = tp->tm_mon;
++    int year_requested = tp->tm_year;
++
++    int mon_remainder = mon % 12;
++    int negative_mon_remainder = mon_remainder < 0;
++    int mon_years = mon / 12 - negative_mon_remainder;
++    int year = year_requested + mon_years;
++    int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
++  	       [mon_remainder + 12 * negative_mon_remainder])
++  	       + mday - 1);
++    if (year < 69) return -1;
++    tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
++    tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
++    t = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
++    if (year == 69)
++    {
++      if (t < 0 || t > 2 * 24 * 60 * 60) return -1;
++    }
++    *tp = tm;
++    return t;
++}
++
++void get_rtc_time (struct rtc_time *rtc_tm)
++{
++    time_t update_time;
++    static time_t old_time = 0;	
++    
++    spin_lock (&rtc_lock);
++    update_time =  RTC_SECOND_REG + RTC_MINUTE_REG * 60 + RTC_HOUR_REG * 60 * 60 + RTC_DAY_REG * 60 * 60 * 24 - local_rtc_offset + set_rtc_offset;
++    if (old_time > 0)
++    {
++      printk ("\n\n Old time is %d, last time is %d, diff is %d\n",old_time,update_time,update_time-old_time);
++      printk (" Throughput is %d B/s, %d KB/s\n\n",106096775/(update_time-old_time),(106096775/1024)/(update_time-old_time));
++    }
++    old_time = update_time;
++    offtime(&update_time, 0, rtc_tm);	
++    if ((rtc_tm->tm_year += (epoch - 1900)) <= 69)
++      rtc_tm->tm_year += 100; 
++    spin_unlock (&rtc_lock);
++}
++
++int set_rtc_time (struct rtc_time *rtc_tm)
++{
++    unsigned char mon, day, hrs, min, sec, leap_yr;
++    unsigned int yrs;
++    
++    spin_lock (&rtc_lock);
++    yrs = rtc_tm->tm_year + 1900;
++    mon = rtc_tm->tm_mon + 1;  
++    day = rtc_tm->tm_mday;
++    hrs = rtc_tm->tm_hour;
++    min = rtc_tm->tm_min;
++    sec = rtc_tm->tm_sec; 
++    if (yrs < 1970) return -EINVAL;
++    leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
++    if ((mon > 12) || (day == 0)) return -EINVAL;
++    if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) return -EINVAL;
++    if ((hrs >= 24) || (min >= 60) || (sec >= 60)) return -EINVAL;
++    if ((yrs -= epoch) > 255) return -EINVAL;   
++    local_rtc_offset = RTC_SECOND_REG + RTC_MINUTE_REG * 60 + RTC_HOUR_REG * 60 * 60 + RTC_DAY_REG * 60 * 60 * 24;
++    set_rtc_offset = _mktime(rtc_tm, 0);
++    spin_unlock (&rtc_lock);
++    return 0;
++}
++
++int set_rtc_alm_time (struct rtc_time *alm_tm)
++{
++    unsigned char hrs, min, sec;
++    unsigned long alm_sec;
++    unsigned int volatile rtc_int_status;
++    
++    spin_lock_irq(&rtc_lock);
++    alm_sec = alm_tm->tm_hour * 3600 + alm_tm->tm_min * 60 + alm_tm->tm_sec;
++    hrs = alm_sec / 3600;
++    min = (alm_sec % 3600) / 60;
++    sec = (alm_sec % 3600) % 60;
++    RTC_ALARM_HOUR_REG = hrs;
++    RTC_ALARM_MINUTE_REG = min;
++    RTC_ALARM_SECOND_REG = sec;
++    RTC_CONTROL_REG = RTC_MATCH_ALARM_ENABLE_BIT;
++    rtc_int_status = RTC_INTERRUPT_STATE_REG;
++    RTC_INTERRUPT_STATE_REG = rtc_int_status;                      
++    spin_unlock_irq(&rtc_lock);    
++    return 0;
++}
++
++static loff_t rtc_lseek(struct file *file, loff_t offset, int origin)
++{
++    return -ESPIPE;
++}
++
++static void mask_rtc_irq_bit(unsigned char bit)
++{
++    unsigned char val;
++    unsigned int volatile rtc_int_status;
++
++    spin_lock_irq(&rtc_lock);
++    val = RTC_CONTROL_REG;
++    val &=  ~bit;
++    RTC_CONTROL_REG = val;
++    rtc_int_status = RTC_INTERRUPT_STATE_REG;
++    spin_unlock_irq(&rtc_lock);
++}
++
++static void set_rtc_irq_bit(unsigned char bit)
++{
++    unsigned char val;
++    unsigned int volatile rtc_int_status;	
++        
++    spin_lock_irq(&rtc_lock);
++    val = RTC_CONTROL_REG;
++    val |= bit;
++    RTC_CONTROL_REG = val;
++    rtc_int_status = RTC_INTERRUPT_STATE_REG;
++    spin_unlock_irq(&rtc_lock);
++}
++
++static void get_rtc_alm_time(struct rtc_time *alm_tm)
++{
++    spin_lock_irq(&rtc_lock);
++    alm_tm->tm_sec = RTC_ALARM_SECOND_REG;
++    alm_tm->tm_min = RTC_ALARM_MINUTE_REG;
++    alm_tm->tm_hour = RTC_ALARM_HOUR_REG;
++    spin_unlock_irq(&rtc_lock);
++}
++
++static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,unsigned long arg)
++{
++    struct rtc_time wtime; 
++
++    switch (cmd)
++    {
++	case RTC_RD_TIME:
++	        memset(&wtime, 0, sizeof(struct rtc_time));
++		get_rtc_time(&wtime);
++		break;
++	case RTC_SET_TIME:
++	{         
++		struct rtc_time rtc_tm;
++		if (!capable(CAP_SYS_TIME))
++		  return -EPERM;
++		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
++		  return -EFAULT;
++		set_rtc_time(&rtc_tm);
++		return 0;
++	}	
++        case RTC_ALM_SET:
++        {
++        	struct rtc_time alm_tm; 
++		if (copy_from_user(&alm_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
++		  return -EFAULT;
++		memset(&wtime, 0, sizeof(struct rtc_time));  
++		set_rtc_alm_time(&alm_tm);
++		return 0;
++	}	
++	case RTC_ALM_READ:
++	        memset(&wtime, 0, sizeof(struct rtc_time));
++		get_rtc_alm_time(&wtime);
++		break;
++	case RTC_AIE_OFF:
++	        mask_rtc_irq_bit(RTC_INTR_ALARM);	
++		return 0;
++	case RTC_AIE_ON:
++	        set_rtc_irq_bit(RTC_INTR_ALARM);
++		return 0;	
++	default:
++		return -EINVAL;
++    }
++    return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
++}
++
++static void rtc_fire(int irq, void *dev_id, struct pt_regs *regs)
++{
++    unsigned int volatile    rtc_int_status;	
++    
++    HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_RTC_BIT_INDEX);
++    HAL_RTC_READ_INTERRUPT_STATUS(rtc_int_status);
++    HAL_RTC_WRITE_INTERRUPT_STATUS(rtc_int_status);
++    if (rtc_int_status & RTC_AUTO_SECOND_ALARM_INTERRUPT_BIT) rtc_interrupt_flag |= RTC_AUTO_SECOND_ALARM_INTERRUPT_BIT;
++    if (rtc_int_status & RTC_AUTO_MINUTE_ALARM_INTERRUPT_BIT) rtc_interrupt_flag |= RTC_AUTO_MINUTE_ALARM_INTERRUPT_BIT;
++    if (rtc_int_status & RTC_AUTO_HOUR_ALARM_INTERRUPT_BIT) rtc_interrupt_flag |= RTC_AUTO_HOUR_ALARM_INTERRUPT_BIT;
++    if (rtc_int_status & RTC_AUTO_DAY_ALARM_INTERRUPT_BIT) rtc_interrupt_flag |= RTC_AUTO_DAY_ALARM_INTERRUPT_BIT;
++    if (rtc_int_status & RTC_MATCH_ALARM_INTERRUPT_BIT) {rtc_interrupt_flag |= RTC_MATCH_ALARM_INTERRUPT_BIT;
++      wake_up_interruptible(&str9100_rtc_wait);
++    }
++    if (rtc_int_status & RTC_BATTERY_LOW_VOLTAGE_INTR_BIT)
++    {
++      rtc_interrupt_flag |= RTC_BATTERY_LOW_VOLTAGE_INTR_BIT;
++      printk("str9100 rtc: Low Battery Voltage!!\n");
++    }
++    if (!(rtc_interrupt_flag & RTC_MATCH_ALARM_INTERRUPT_BIT)) HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_RTC_BIT_INDEX);
++}
++
++static void rtc_str9100_hwinit(int ctrl, int hour, int min, int sec)
++{    	
++    RTC_CONTROL_REG &= ~(RTC_ENABLE_BIT);	
++    if (ctrl & RTC_MATCH_ALARM_ENABLE_BIT)
++    {
++      RTC_ALARM_SECOND_REG = sec;
++      RTC_ALARM_MINUTE_REG = min;
++      RTC_ALARM_HOUR_REG = hour;    	
++    }else{
++      RTC_ALARM_SECOND_REG = 0;
++      RTC_ALARM_MINUTE_REG = 0;
++      RTC_ALARM_HOUR_REG = 0;
++    } 
++    RTC_CONTROL_REG = ctrl;
++} 
++
++static int rtc_open(struct inode *inode, struct file *file)
++{
++    if (rtc_busy) return -EBUSY;
++
++    rtc_busy = 1;
++    return 0;
++}
++
++static ssize_t rtc_read(struct file * file, char *buf, size_t count, loff_t * ppos)
++{
++    DECLARE_WAITQUEUE(wait, current);
++    unsigned long data;
++    ssize_t retval;
++
++    if (count < sizeof(unsigned long))
++      return -EINVAL;
++
++    add_wait_queue(&str9100_rtc_wait, &wait);
++    set_current_state(TASK_INTERRUPTIBLE);
++    for (;;) {
++	spin_lock(&rtc_lock);
++	data = rtc_interrupt_flag;
++	if (data != 0) {
++	  rtc_interrupt_flag = 0;
++	  break;
++	}
++        spin_unlock(&rtc_lock);
++        if (file->f_flags & O_NONBLOCK) {
++	  retval = -EAGAIN;
++	  goto out;
++	}
++	if (signal_pending(current)) {
++	  retval = -ERESTARTSYS;
++	  goto out;
++	}
++        schedule();
++    }
++    spin_unlock(&rtc_lock);
++    retval = put_user(data, (unsigned long *) buf);
++    if (!retval) retval = sizeof(unsigned long);
++out:
++    mask_rtc_irq_bit(RTC_INTR_ALARM);
++    set_current_state(TASK_RUNNING);
++    remove_wait_queue(&str9100_rtc_wait, &wait);
++    return retval;
++}
++
++static int rtc_release(struct inode *inode, struct file *file)
++{
++    rtc_busy = 0;
++    return 0;
++}
++
++static struct file_operations rtc_fops = {
++    owner:	THIS_MODULE,
++    llseek:	rtc_lseek,
++    ioctl:	rtc_ioctl,
++    open:	rtc_open,
++    read:       rtc_read,
++    release:	rtc_release
++};
++
++static struct miscdevice rtc_dev = { RTC_MINOR, "rtc", &rtc_fops };
++
++static int rtc_proc_output (char *buf)
++{
++    char *p;
++    struct rtc_time tm;
++    
++    p = buf;
++    get_rtc_time(&tm);
++    p += sprintf(p,"rtc_time\t: %02d:%02d:%02d\n"
++		   "rtc_date\t: %04d-%02d-%02d\n"
++	 	   "rtc_epoch\t: %04lu\n",
++		   tm.tm_hour, tm.tm_min, tm.tm_sec,
++		   tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
++    get_rtc_alm_time(&tm);
++    p += sprintf(p, "alarm\t\t: ");
++    if (tm.tm_hour <= 24)
++      p += sprintf(p, "%02d:", tm.tm_hour);
++    else
++      p += sprintf(p, "**:");
++    if (tm.tm_min <= 59)
++      p += sprintf(p, "%02d:", tm.tm_min);
++    else
++      p += sprintf(p, "**:");
++    if (tm.tm_sec <= 59)
++      p += sprintf(p, "%02d\n", tm.tm_sec);
++    else
++      p += sprintf(p, "**\n");	
++    return  p - buf;
++}
++
++static int rtc_read_proc(char *page, char **start, off_t off,int count, int *eof, void *data)
++{
++    int len = rtc_proc_output (page);
++    
++    if (len <= off+count) *eof = 1;
++    *start = page + off;
++    len -= off;
++    if (len>count) len = count;
++    if (len<0) len = 0;
++    return len;
++}
++
++static int __init str9100_rtc_init(void)
++{
++    int error;
++
++    error = misc_register(&rtc_dev);
++    if (error) {
++      printk(KERN_ERR "rtc: unable to get misc minor\n");
++      return error;
++    }	
++    printk(KERN_INFO "STR9100 Real Time Clock Driver v" STR9100_RTC_VERSION "\n");
++    rtc_str9100_hwinit(0,0,0,0);
++    HAL_RTC_ENABLE();
++    request_irq(INTC_RTC_BIT_INDEX, rtc_fire, 0, DEVICE_NAME, NULL);
++    create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL);
++    local_rtc_offset = 0;
++    set_rtc_offset = current_rtc_time = 0;        
++    return 0;
++}
++
++static void __exit str9100_rtc_exit (void)
++{
++    char buf[64];
++    	
++    HAL_RTC_DISABLE();		
++    cleanup_sysctl();
++    sprintf (buf,"driver/%s",DEVICE_NAME);
++    remove_proc_entry (buf, NULL);
++    misc_deregister(&rtc_dev);
++    free_irq (INTC_RTC_BIT_INDEX, NULL);
++}
++
++module_init(str9100_rtc_init);
++module_exit(str9100_rtc_exit);
++
++MODULE_LICENSE("GPL");
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_setup.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_setup.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_setup.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_setup.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,357 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/mm.h>
++#include <linux/init.h>
++#include <linux/config.h>
++#include <linux/major.h>
++#include <linux/fs.h>
++#include <linux/platform_device.h>
++#include <linux/serial.h>
++#include <linux/tty.h>
++#include <linux/serial_8250.h>
++
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/page.h>
++#include <asm/mach/map.h>
++#include <asm/setup.h>
++#include <asm/system.h>
++#include <asm/memory.h>
++#include <asm/hardware.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++
++#define STR9100_UART_XTAL 14769230
++
++#define EARLY_REGISTER_CONSOLE
++
++/*
++ * Standard IO mapping
++ */
++static struct map_desc str9100_std_desc[] __initdata = {
++	{
++		.virtual	= SYSVA_FLASH_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_FLASH_BASE_ADDR),
++		.length		= SZ_8M,
++		.type		= MT_DEVICE
++	}, 	{
++		.virtual	= SYSVA_SMC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_SMC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_DDR_SDRAM_CONTROLLER_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_DDR_SDRAM_CONTROLLER_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_DMAC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_DMAC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_GSW_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_GSW_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_HNAT_SRAM_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_HNAT_SRAM_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_MISC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_MISC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_POWER_MANAGEMENT_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_POWER_MANAGEMENT_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_UART_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_UART_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_TIMER_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_TIMER_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_WATCHDOG_TIMER_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_WATCHDOG_TIMER_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_RTC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_RTC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_GPIO_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_GPIO_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_INTC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_INTC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_PCMCIA_CONTROLLER_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_PCMCIA_CONTROLLER_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB11_CONFIG_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB11_CONFIG_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB11_OPERATION_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB11_OPERATION_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB20_CONFIG_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB20_CONFIG_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB20_OPERATION_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB20_OPERATION_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}
++};
++
++#ifdef EARLY_REGISTER_CONSOLE
++static struct uart_port str9100_serial_ports[] = {
++	{
++		.membase	= (char*)(SYSVA_UART_BASE_ADDR),
++		.mapbase	= (SYSPA_UART_BASE_ADDR),
++		.irq		= INTC_UART_BIT_INDEX,
++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++		.iotype		= UPIO_MEM,
++		.regshift	= 2,
++		.uartclk	= STR9100_UART_XTAL,
++		.line		= 0,
++		.type		= PORT_16550A,
++		.fifosize	= 16
++	}
++};
++#else
++static struct resource str9100_uart0_resources[] = {
++	[0] = {
++		.start	= SYSPA_UART_BASE_ADDR,
++		.end	= SYSPA_UART_BASE_ADDR + 0xff,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_UART_BIT_INDEX,
++		.end	= INTC_UART_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ
++	}
++};
++
++static struct plat_serial8250_port str9100_uart0_data[] = {
++	{
++		.membase	= (char*)(SYSVA_UART_BASE_ADDR),
++		.mapbase	= (SYSPA_UART_BASE_ADDR),
++		.irq		= INTC_UART_BIT_INDEX,
++		.uartclk	= STR9100_UART_XTAL,
++		.regshift	= 2,
++		.iotype		= UPIO_MEM,
++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++	},
++	{  },
++};
++
++static struct platform_device str9100_uart0_device = {
++	.name			= "serial8250",
++	.id			= 0,
++	.dev.platform_data	= str9100_uart0_data,
++	.num_resources		= 2,
++	.resource		= str9100_uart0_resources,
++};
++#endif
++
++static u64 usb_dmamask = 0xffffffffULL;
++static struct resource str9100_usb11_resources[] = {
++	[0] = {
++		.start	= SYSPA_USB11_CONFIG_BASE_ADDR,
++		.end	= SYSPA_USB11_CONFIG_BASE_ADDR + SZ_1M - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_USB11_BIT_INDEX,
++		.end	= INTC_USB11_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device str9100_usb11_device = {
++	.name		= "str9100-ohci",
++	.id		= -1,
++	.dev = {
++		.dma_mask		= &usb_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.resource	= str9100_usb11_resources,
++	.num_resources	= ARRAY_SIZE(str9100_usb11_resources),
++};
++
++static struct resource str9100_usb20_resources[] = {
++	[0] = {
++		.start	= SYSPA_USB20_CONFIG_BASE_ADDR,
++		.end	= SYSPA_USB20_CONFIG_BASE_ADDR + SZ_1M - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_USB20_BIT_INDEX,
++		.end	= INTC_USB20_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device str9100_usb20_device = {
++	.name		= "str9100-ehci",
++	.id		= -1,
++	.dev		= {
++		.dma_mask		= &usb_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.resource	= str9100_usb20_resources,
++	.num_resources	= ARRAY_SIZE(str9100_usb20_resources),
++};
++
++static struct platform_device *str9100_devices[] __initdata = {
++#ifndef EARLY_REGISTER_CONSOLE
++	&str9100_uart0_device,
++#endif
++	&str9100_usb11_device,
++	&str9100_usb20_device
++};
++
++static void __init str9100_fixup(struct machine_desc *desc,
++	struct tag *tags, char **cmdline, struct meminfo *mi)
++{
++        mi->nr_banks = 1;
++	mi->bank[0].start = CONFIG_SYSTEM_DRAM_BASE;
++	mi->bank[0].size = CONFIG_SYSTEM_DRAM_SIZE << 20;
++	mi->bank[0].node = 0;
++}
++
++/* ######################################################################### */
++#ifdef CONFIG_CPU_ISPAD_ENABLE 
++extern unsigned long __ispad_begin; 
++extern int str9100_enable_ispad(unsigned long); 
++#endif
++u32 CPU_clock;
++u32 AHB_clock;
++u32 APB_clock;
++// This function is called just after the
++// page table and cpu have been initialized
++void __init str9100_early_init(void)
++{
++	switch ((PWRMGT_RESET_LATCH_CONFIGURATION_REG >> 6) & 0x03) {
++	case 0x00:
++		CPU_clock = 175000000;
++		break;
++
++	case 0x01:
++		CPU_clock = 200000000;
++		break;
++
++	case 0x02:
++		CPU_clock = 225000000;
++		break;
++
++	case 0x03:
++		CPU_clock = 250000000;
++		break;
++	}
++
++	AHB_clock = CPU_clock >> 1;
++	APB_clock = AHB_clock >> 1;
++
++	printk("CPU clock at %dMHz\n", CPU_clock / 1000000);
++	printk("AHB clock at %dMHz\n", AHB_clock / 1000000);
++	printk("APB clock at %dMHz\n", APB_clock / 1000000);
++
++#ifdef CONFIG_CPU_ISPAD_ENABLE
++	str9100_enable_ispad((unsigned long)&__ispad_begin);
++#endif
++}
++/* ######################################################################### */
++
++void __init str9100_init(void)
++{
++#if 1
++	platform_add_devices(str9100_devices, ARRAY_SIZE(str9100_devices));
++#else
++#ifndef EARLY_REGISTER_CONSOLE
++	platform_device_register(&str9100_uart0_device);
++#endif
++	platform_device_register(&str9100_usb11_device);
++	platform_device_register(&str9100_usb20_device);
++#endif
++}
++
++extern void str9100_register_map_desc(struct map_desc *map, int count);
++void __init str9100_map_io(void)
++{
++	iotable_init(str9100_std_desc, ARRAY_SIZE(str9100_std_desc));
++	str9100_register_map_desc(str9100_std_desc, ARRAY_SIZE(str9100_std_desc));
++#ifdef EARLY_REGISTER_CONSOLE
++	early_serial_setup(&str9100_serial_ports[0]);
++#endif
++}
++
++extern void str9100_init_irq(void);
++extern struct sys_timer str9100_timer;
++
++MACHINE_START(STR9100, "STAR STR9100")
++	.phys_io	= SYSPA_UART_BASE_ADDR,
++	.io_pg_offst	= ((SYSVA_UART_BASE_ADDR) >> 18) & 0xfffc, // virtual, physical
++	.fixup		= str9100_fixup,
++	.map_io		= str9100_map_io,
++	.init_irq	= str9100_init_irq,
++	.timer		= &str9100_timer,
++	.boot_params	= 0x0100,
++	.init_machine	= str9100_init,
++MACHINE_END
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_timer.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_timer.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_timer.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_timer.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,219 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/time.h>
++#include <linux/init.h>
++#include <linux/timex.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/time.h>
++
++#if 1
++// for timer clock < 100MHz
++#define uSECS_PER_TICK	(1000000 / APB_clock)
++#define TICKS2USECS(x)  ((x) * uSECS_PER_TICK)
++#else
++// for timer clock >= 100MHz
++#define TICKS_PER_uSEC	(APB_clock / 1000000)
++#define TICKS2USECS(x)  ((x) / TICKS_PER_uSEC)
++#endif
++
++extern u32 APB_clock;
++static u32 timer_counter_value;
++
++static inline unsigned int str9100_read_timer_counter(void)
++{
++	return TIMER1_COUNTER_REG;
++}
++
++static inline unsigned int str9100_read_timer_interrupt_status(void)
++{
++	return TIMER_INTERRUPT_STATUS_REG;
++}
++
++static inline void str9100_clear_timer_interrupt_status(unsigned int irq)
++{
++	TIMER_INTERRUPT_STATUS_REG &= ~(1 << TIMER1_OVERFLOW_INTERRUPT_BIT_INDEX);
++}
++
++static void str9100_setup_timer(unsigned int counter_value)
++{
++	unsigned long control_value;
++	unsigned long mask_value;    
++
++	control_value = TIMER_CONTROL_REG;
++	mask_value = TIMER_INTERRUPT_MASK_REG;
++
++	TIMER1_COUNTER_REG = counter_value;
++	TIMER1_AUTO_RELOAD_VALUE_REG = counter_value;
++	TIMER1_MATCH_VALUE1_REG = 0;
++	TIMER1_MATCH_VALUE2_REG = 0;
++
++	// Clock Source: PCLK
++	control_value &= ~(1 << TIMER1_CLOCK_SOURCE_BIT_INDEX);
++
++	// Down Count Mode
++	control_value |= (1 << TIMER1_UP_DOWN_COUNT_BIT_INDEX);
++
++	// un-mask overflow, match2 and match1 interrupt sources
++	mask_value &= ~(0x7);
++
++	// mask match2 and match1 interrupt sources
++	mask_value |= 0x03;
++
++	TIMER_CONTROL_REG = control_value;
++	TIMER_INTERRUPT_MASK_REG = mask_value;
++}
++
++static void str9100_timer_enable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER_CONTROL_REG;
++
++	// enable overflow mode
++	control_value |= (1 << TIMER1_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// enable the timer
++	control_value |= (1 << TIMER1_ENABLE_BIT_INDEX);
++
++	TIMER_CONTROL_REG = control_value;
++}
++
++static void str9100_timer_disable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER_CONTROL_REG;
++
++	// disable overflow mode
++	control_value &= ~(1 << TIMER1_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// disable the timer
++	control_value &= ~(1 << TIMER1_ENABLE_BIT_INDEX);
++
++	TIMER_CONTROL_REG = control_value;
++}
++
++/*
++ * Returns number of us since last clock interrupt.  Note that interrupts
++ * will have been disabled by do_gettimeoffset()
++ */
++static unsigned long str9100_gettimeoffset(void)
++{
++	unsigned long ticks1, ticks2;
++	unsigned long interrupt_status;
++
++	/*
++	 * Get the current number of ticks.  Note that there is a race
++	 * condition between us reading the timer and checking for
++	 * an interrupt.  We get around this by ensuring that the
++	 * counter has not reloaded between our two reads.
++	 */
++	ticks2 = str9100_read_timer_counter();
++	do {
++		ticks1 = ticks2;
++		interrupt_status = str9100_read_timer_interrupt_status();
++		ticks2 = str9100_read_timer_counter();
++	} while (ticks2 > ticks1);
++
++	/*
++	 * Number of ticks since last interrupt
++	 */
++	ticks1 = timer_counter_value - ticks2;
++
++	/*
++	 * Interrupt pending?  If so, we've reloaded once already.
++	 */
++	if (interrupt_status) {
++		ticks1 += timer_counter_value;
++	}
++
++	/*
++	 * Convert the ticks to usecs
++	 */
++	return TICKS2USECS(ticks1);
++}
++
++/*
++ * IRQ handler for the timer
++ */
++static irqreturn_t
++str9100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	write_seqlock(&xtime_lock);
++
++	str9100_clear_timer_interrupt_status((unsigned int)irq);
++	/* 2008/05/12 Richard 
++	timer_tick(regs);
++	 */
++	timer_tick();
++
++	write_sequnlock(&xtime_lock);
++
++	return IRQ_HANDLED;
++}
++
++static struct irqaction str9100_timer_irq = {
++	.name		= "STR9100 Timer Tick",
++/* 2008/05/12 Richard
++	.flags		= SA_INTERRUPT | SA_TIMER,
++ */
++	.flags          = IRQF_DISABLED | IRQF_TIMER,
++	.handler	= str9100_timer_interrupt,
++};
++
++/*
++ * Set up timer interrupt, and return the current time in seconds.
++ */
++static void __init str9100_timer_init(void)
++{
++	/*
++	 * prepare timer-related values
++	 */
++	timer_counter_value = APB_clock / HZ;
++
++	/*
++	 * setup timer-related values
++	 */
++	str9100_setup_timer(timer_counter_value);
++
++	/*
++	 * Make irqs happen for the system timer
++	 */
++	setup_irq(INTC_TIMER1_BIT_INDEX, &str9100_timer_irq);
++
++	str9100_timer_enable();
++}
++
++struct sys_timer str9100_timer = {
++	.init		= str9100_timer_init,
++	.offset		= str9100_gettimeoffset,
++};
++
+diff -rupN linux-2.6.35.11/arch/arm/Makefile linux-2.6.35.11-ts7500/arch/arm/Makefile
+--- linux-2.6.35.11/arch/arm/Makefile	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -18,6 +18,7 @@ endif
+ OBJCOPYFLAGS	:=-O binary -R .note -R .note.gnu.build-id -R .comment -S
+ GZFLAGS		:=-9
+ #KBUILD_CFLAGS	+=-pipe
++KBUILD_CFLAGS	+=-pipe -gdwarf-2
+ # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
+ KBUILD_CFLAGS	+=$(call cc-option,-marm,)
+ 
+@@ -186,6 +187,10 @@ machine-$(CONFIG_MACH_SPEAR300)		:= spea
+ machine-$(CONFIG_MACH_SPEAR310)		:= spear3xx
+ machine-$(CONFIG_MACH_SPEAR320)		:= spear3xx
+ machine-$(CONFIG_MACH_SPEAR600)		:= spear6xx
++machine-$(CONFIG_ARCH_STR9100)    := str9100
++machine-$(CONFIG_ARCH_STR8100)    := str8100
++
++
+ 
+ # Platform directory name.  This list is sorted alphanumerically
+ # by CONFIG_* macro name.
+diff -rupN linux-2.6.35.11/arch/arm/Makefile.orig linux-2.6.35.11-ts7500/arch/arm/Makefile.orig
+--- linux-2.6.35.11/arch/arm/Makefile.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/Makefile.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,294 @@
++#
++# arch/arm/Makefile
++#
++# This file is included by the global makefile so that you can add your own
++# architecture-specific flags and dependencies.
++#
++# This file is subject to the terms and conditions of the GNU General Public
++# License.  See the file "COPYING" in the main directory of this archive
++# for more details.
++#
++# Copyright (C) 1995-2001 by Russell King
++
++LDFLAGS_vmlinux	:=-p --no-undefined -X
++ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
++LDFLAGS_vmlinux	+= --be8
++endif
++
++OBJCOPYFLAGS	:=-O binary -R .note -R .note.gnu.build-id -R .comment -S
++GZFLAGS		:=-9
++#KBUILD_CFLAGS	+=-pipe
++# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
++KBUILD_CFLAGS	+=$(call cc-option,-marm,)
++
++# Do not use arch/arm/defconfig - it's always outdated.
++# Select a platform tht is kept up-to-date
++KBUILD_DEFCONFIG := versatile_defconfig
++
++# defines filename extension depending memory management type.
++ifeq ($(CONFIG_MMU),)
++MMUEXT		:= -nommu
++endif
++
++ifeq ($(CONFIG_FRAME_POINTER),y)
++KBUILD_CFLAGS	+=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
++endif
++
++ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
++KBUILD_CPPFLAGS	+= -mbig-endian
++AS		+= -EB
++LD		+= -EB
++else
++KBUILD_CPPFLAGS	+= -mlittle-endian
++AS		+= -EL
++LD		+= -EL
++endif
++
++comma = ,
++
++# This selects which instruction set is used.
++# Note that GCC does not numerically define an architecture version
++# macro, but instead defines a whole series of macros which makes
++# testing for a specific architecture or later rather impossible.
++arch-$(CONFIG_CPU_32v7)		:=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
++arch-$(CONFIG_CPU_32v6)		:=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
++# Only override the compiler option if ARMv6. The ARMv6K extensions are
++# always available in ARMv7
++ifeq ($(CONFIG_CPU_32v6),y)
++arch-$(CONFIG_CPU_32v6K)	:=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
++endif
++arch-$(CONFIG_CPU_32v5)		:=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t)
++arch-$(CONFIG_CPU_32v4T)	:=-D__LINUX_ARM_ARCH__=4 -march=armv4t
++arch-$(CONFIG_CPU_32v4)		:=-D__LINUX_ARM_ARCH__=4 -march=armv4
++arch-$(CONFIG_CPU_32v3)		:=-D__LINUX_ARM_ARCH__=3 -march=armv3
++
++# This selects how we optimise for the processor.
++tune-$(CONFIG_CPU_ARM610)	:=-mtune=arm610
++tune-$(CONFIG_CPU_ARM710)	:=-mtune=arm710
++tune-$(CONFIG_CPU_ARM7TDMI)	:=-mtune=arm7tdmi
++tune-$(CONFIG_CPU_ARM720T)	:=-mtune=arm7tdmi
++tune-$(CONFIG_CPU_ARM740T)	:=-mtune=arm7tdmi
++tune-$(CONFIG_CPU_ARM9TDMI)	:=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_ARM940T)	:=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_ARM946E)	:=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi)
++tune-$(CONFIG_CPU_ARM920T)	:=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_ARM922T)	:=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_ARM925T)	:=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_ARM926T)	:=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_FA526)	:=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_SA110)	:=-mtune=strongarm110
++tune-$(CONFIG_CPU_SA1100)	:=-mtune=strongarm1100
++tune-$(CONFIG_CPU_XSCALE)	:=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
++tune-$(CONFIG_CPU_XSC3)		:=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
++tune-$(CONFIG_CPU_FEROCEON)	:=$(call cc-option,-mtune=marvell-f,-mtune=xscale)
++tune-$(CONFIG_CPU_V6)		:=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
++
++ifeq ($(CONFIG_AEABI),y)
++CFLAGS_ABI	:=-mabi=aapcs-linux -mno-thumb-interwork
++else
++CFLAGS_ABI	:=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
++endif
++
++ifeq ($(CONFIG_ARM_UNWIND),y)
++CFLAGS_ABI	+=-funwind-tables
++endif
++
++ifeq ($(CONFIG_THUMB2_KERNEL),y)
++AFLAGS_AUTOIT	:=$(call as-option,-Wa$(comma)-mimplicit-it=always,-Wa$(comma)-mauto-it)
++AFLAGS_NOWARN	:=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W)
++CFLAGS_THUMB2	:=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN)
++AFLAGS_THUMB2	:=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb
++endif
++
++# Need -Uarm for gcc < 3.x
++KBUILD_CFLAGS	+=$(CFLAGS_ABI) $(CFLAGS_THUMB2) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
++KBUILD_AFLAGS	+=$(CFLAGS_ABI) $(AFLAGS_THUMB2) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
++
++CHECKFLAGS	+= -D__arm__
++
++#Default value
++head-y		:= arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
++textofs-y	:= 0x00008000
++textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000
++# We don't want the htc bootloader to corrupt kernel during resume
++textofs-$(CONFIG_PM_H1940)      := 0x00108000
++# SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
++ifeq ($(CONFIG_ARCH_SA1100),y)
++textofs-$(CONFIG_SA1111) := 0x00208000
++endif
++
++# Machine directory name.  This list is sorted alphanumerically
++# by CONFIG_* macro name.
++machine-$(CONFIG_ARCH_AAEC2000)		:= aaec2000
++machine-$(CONFIG_ARCH_AT91)		:= at91
++machine-$(CONFIG_ARCH_BCMRING)		:= bcmring
++machine-$(CONFIG_ARCH_CLPS711X)		:= clps711x
++machine-$(CONFIG_ARCH_CNS3XXX)		:= cns3xxx
++machine-$(CONFIG_ARCH_DAVINCI)		:= davinci
++machine-$(CONFIG_ARCH_DOVE)		:= dove
++machine-$(CONFIG_ARCH_EBSA110)		:= ebsa110
++machine-$(CONFIG_ARCH_EP93XX)		:= ep93xx
++machine-$(CONFIG_ARCH_GEMINI)		:= gemini
++machine-$(CONFIG_ARCH_H720X)		:= h720x
++machine-$(CONFIG_ARCH_INTEGRATOR)	:= integrator
++machine-$(CONFIG_ARCH_IOP13XX)		:= iop13xx
++machine-$(CONFIG_ARCH_IOP32X)		:= iop32x
++machine-$(CONFIG_ARCH_IOP33X)		:= iop33x
++machine-$(CONFIG_ARCH_IXP2000)		:= ixp2000
++machine-$(CONFIG_ARCH_IXP23XX)		:= ixp23xx
++machine-$(CONFIG_ARCH_IXP4XX)		:= ixp4xx
++machine-$(CONFIG_ARCH_KIRKWOOD)		:= kirkwood
++machine-$(CONFIG_ARCH_KS8695)		:= ks8695
++machine-$(CONFIG_ARCH_L7200)		:= l7200
++machine-$(CONFIG_ARCH_LH7A40X)		:= lh7a40x
++machine-$(CONFIG_ARCH_LOKI) 		:= loki
++machine-$(CONFIG_ARCH_MMP)		:= mmp
++machine-$(CONFIG_ARCH_MSM)		:= msm
++machine-$(CONFIG_ARCH_MV78XX0)		:= mv78xx0
++machine-$(CONFIG_ARCH_MX1)		:= mx1
++machine-$(CONFIG_ARCH_MX2)		:= mx2
++machine-$(CONFIG_ARCH_MX25)		:= mx25
++machine-$(CONFIG_ARCH_MX3)		:= mx3
++machine-$(CONFIG_ARCH_MX5)		:= mx5
++machine-$(CONFIG_ARCH_MXC91231)		:= mxc91231
++machine-$(CONFIG_ARCH_NETX)		:= netx
++machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
++machine-$(CONFIG_ARCH_NS9XXX)		:= ns9xxx
++machine-$(CONFIG_ARCH_OMAP1)		:= omap1
++machine-$(CONFIG_ARCH_OMAP2)		:= omap2
++machine-$(CONFIG_ARCH_OMAP3)		:= omap2
++machine-$(CONFIG_ARCH_OMAP4)		:= omap2
++machine-$(CONFIG_ARCH_ORION5X)		:= orion5x
++machine-$(CONFIG_ARCH_PNX4008)		:= pnx4008
++machine-$(CONFIG_ARCH_PXA)		:= pxa
++machine-$(CONFIG_ARCH_REALVIEW)		:= realview
++machine-$(CONFIG_ARCH_RPC)		:= rpc
++machine-$(CONFIG_ARCH_S3C2410)		:= s3c2410 s3c2400 s3c2412 s3c2416 s3c2440 s3c2443
++machine-$(CONFIG_ARCH_S3C24A0)		:= s3c24a0
++machine-$(CONFIG_ARCH_S3C64XX)		:= s3c64xx
++machine-$(CONFIG_ARCH_S5P6440)		:= s5p6440
++machine-$(CONFIG_ARCH_S5P6442)		:= s5p6442
++machine-$(CONFIG_ARCH_S5PC100)		:= s5pc100
++machine-$(CONFIG_ARCH_S5PV210)		:= s5pv210
++machine-$(CONFIG_ARCH_SA1100)		:= sa1100
++machine-$(CONFIG_ARCH_SHARK)		:= shark
++machine-$(CONFIG_ARCH_SHMOBILE) 	:= shmobile
++machine-$(CONFIG_ARCH_STMP378X)		:= stmp378x
++machine-$(CONFIG_ARCH_STMP37XX)		:= stmp37xx
++machine-$(CONFIG_ARCH_U300)		:= u300
++machine-$(CONFIG_ARCH_U8500)		:= ux500
++machine-$(CONFIG_ARCH_VERSATILE)	:= versatile
++machine-$(CONFIG_ARCH_VEXPRESS)		:= vexpress
++machine-$(CONFIG_ARCH_W90X900)		:= w90x900
++machine-$(CONFIG_ARCH_NUC93X)		:= nuc93x
++machine-$(CONFIG_FOOTBRIDGE)		:= footbridge
++machine-$(CONFIG_MACH_SPEAR300)		:= spear3xx
++machine-$(CONFIG_MACH_SPEAR310)		:= spear3xx
++machine-$(CONFIG_MACH_SPEAR320)		:= spear3xx
++machine-$(CONFIG_MACH_SPEAR600)		:= spear6xx
++
++# Platform directory name.  This list is sorted alphanumerically
++# by CONFIG_* macro name.
++plat-$(CONFIG_ARCH_MXC)		:= mxc
++plat-$(CONFIG_ARCH_OMAP)	:= omap
++plat-$(CONFIG_ARCH_S3C64XX)	:= samsung
++plat-$(CONFIG_ARCH_STMP3XXX)	:= stmp3xxx
++plat-$(CONFIG_PLAT_IOP)		:= iop
++plat-$(CONFIG_PLAT_NOMADIK)	:= nomadik
++plat-$(CONFIG_PLAT_ORION)	:= orion
++plat-$(CONFIG_PLAT_PXA)		:= pxa
++plat-$(CONFIG_PLAT_S3C24XX)	:= s3c24xx samsung
++plat-$(CONFIG_PLAT_S5P)		:= s5p samsung
++plat-$(CONFIG_PLAT_SPEAR)	:= spear
++plat-$(CONFIG_PLAT_VERSATILE)	:= versatile
++
++ifeq ($(CONFIG_ARCH_EBSA110),y)
++# This is what happens if you forget the IOCS16 line.
++# PCMCIA cards stop working.
++CFLAGS_3c589_cs.o :=-DISA_SIXTEEN_BIT_PERIPHERAL
++export CFLAGS_3c589_cs.o
++endif
++
++# The byte offset of the kernel image in RAM from the start of RAM.
++TEXT_OFFSET := $(textofs-y)
++
++# The first directory contains additional information for the boot setup code
++ifneq ($(machine-y),)
++MACHINE  := arch/arm/mach-$(word 1,$(machine-y))/
++else
++MACHINE  :=
++endif
++
++machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
++platdirs := $(patsubst %,arch/arm/plat-%/,$(plat-y))
++
++ifeq ($(KBUILD_SRC),)
++KBUILD_CPPFLAGS += $(patsubst %,-I%include,$(machdirs) $(platdirs))
++else
++KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs) $(platdirs))
++endif
++
++export	TEXT_OFFSET GZFLAGS MMUEXT
++
++# Do we have FASTFPE?
++FASTFPE		:=arch/arm/fastfpe
++ifeq ($(FASTFPE),$(wildcard $(FASTFPE)))
++FASTFPE_OBJ	:=$(FASTFPE)/
++endif
++
++# If we have a machine-specific directory, then include it in the build.
++core-y				+= arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
++core-y				+= $(machdirs) $(platdirs)
++core-$(CONFIG_FPE_NWFPE)	+= arch/arm/nwfpe/
++core-$(CONFIG_FPE_FASTFPE)	+= $(FASTFPE_OBJ)
++core-$(CONFIG_VFP)		+= arch/arm/vfp/
++
++drivers-$(CONFIG_OPROFILE)      += arch/arm/oprofile/
++
++libs-y				:= arch/arm/lib/ $(libs-y)
++
++# Default target when executing plain make
++ifeq ($(CONFIG_XIP_KERNEL),y)
++KBUILD_IMAGE := xipImage
++else
++KBUILD_IMAGE := zImage
++endif
++
++all:	$(KBUILD_IMAGE)
++
++boot := arch/arm/boot
++
++archprepare:
++	$(Q)$(MAKE) $(build)=arch/arm/tools include/generated/mach-types.h
++
++# Convert bzImage to zImage
++bzImage: zImage
++
++zImage Image xipImage bootpImage uImage: vmlinux
++	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
++
++zinstall install: vmlinux
++	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
++
++# We use MRPROPER_FILES and CLEAN_FILES now
++archclean:
++	$(Q)$(MAKE) $(clean)=$(boot)
++
++# My testing targets (bypasses dependencies)
++bp:;	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage
++i zi:;	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
++
++
++define archhelp
++  echo  '* zImage        - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
++  echo  '  Image         - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
++  echo  '* xipImage      - XIP kernel image, if configured (arch/$(ARCH)/boot/xipImage)'
++  echo  '  uImage        - U-Boot wrapped zImage'
++  echo  '  bootpImage    - Combined zImage and initial RAM disk' 
++  echo  '                  (supply initrd image via make variable INITRD=<path>)'
++  echo  '  install       - Install uncompressed kernel'
++  echo  '  zinstall      - Install compressed kernel'
++  echo  '                  Install using (your) ~/bin/$(INSTALLKERNEL) or'
++  echo  '                  (distribution) /sbin/$(INSTALLKERNEL) or'
++  echo  '                  install to $$(INSTALL_PATH) and run lilo'
++endef
+diff -rupN linux-2.6.35.11/arch/arm/mm/cache-fa.S linux-2.6.35.11-ts7500/arch/arm/mm/cache-fa.S
+--- linux-2.6.35.11/arch/arm/mm/cache-fa.S	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/cache-fa.S	2011-03-14 11:18:24.000000000 -0400
+@@ -1,3 +1,4 @@
++#if (1)
+ /*
+  *  linux/arch/arm/mm/cache-fa.S
+  *
+@@ -34,6 +35,7 @@
+ #define CACHE_DSIZE	16384 
+ #endif 
+ 
++
+ /* FIXME: put optimal value here. Current one is just estimation */
+ #define CACHE_DLIMIT	(CACHE_DSIZE * 2)
+ 
+@@ -142,7 +144,9 @@ ENTRY(fa_flush_kern_dcache_area)
+ 	cmp	r0, r1
+ 	blo	1b
+ 	mov	r0, #0
++/*
+ 	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
++*/
+ 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
+ 	mov	pc, lr
+ 
+@@ -157,7 +161,7 @@ ENTRY(fa_flush_kern_dcache_area)
+  *	- start  - virtual start address
+  *	- end	 - virtual end address
+  */
+-fa_dma_inv_range:
++ENTRY(fa_dma_inv_range)
+ 	tst	r0, #CACHE_DLINESIZE - 1
+ 	bic	r0, r0, #CACHE_DLINESIZE - 1
+ 	mcrne	p15, 0, r0, c7, c14, 1		@ clean & invalidate D entry
+@@ -180,7 +184,7 @@ fa_dma_inv_range:
+  *	- start  - virtual start address
+  *	- end	 - virtual end address
+  */
+-fa_dma_clean_range:
++ENTRY(fa_dma_clean_range)
+ 	bic	r0, r0, #CACHE_DLINESIZE - 1
+ 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+ 	add	r0, r0, #CACHE_DLINESIZE
+@@ -229,6 +233,10 @@ ENTRY(fa_dma_unmap_area)
+ 	mov	pc, lr
+ ENDPROC(fa_dma_unmap_area)
+ 
++
++
++
++
+ 	__INITDATA
+ 
+ 	.type	fa_cache_fns, #object
+@@ -243,3 +251,408 @@ ENTRY(fa_cache_fns)
+ 	.long	fa_dma_unmap_area
+ 	.long	fa_dma_flush_range
+ 	.size	fa_cache_fns, . - fa_cache_fns
++#else
++
++/* Most of the following is from 2.6.24-cavium */
++
++/*
++ *  linux/arch/arm/mm/cache-fa.S
++ *
++ *  Copyright (C) 2005 Faraday Corp.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  Processors: FA520 FA526 FA626	
++ * 03/31/2005 :	Luke Lee created, modified from cache-v4wb.S
++ * 04/06/2005 :	1. Read CR0-1 and determine the cache size dynamically,
++ *		   to suit all Faraday CPU series
++ *	        2. Fixed all functions
++ * 04/08/2005 :	insert CONFIG_CPU_ICACHE_DISABLE and CONFIG_CPU_DCACHE_DISABLE
++ * 04/12/2005 :	TODO: make this processor dependent or a self-modifying code to 
++ *	        inline cache len/size info into the instructions, as reading cache 
++ *	        size and len info in memory could cause another cache miss.
++ * 05/05/2005 :	Modify fa_flush_user_cache_range to comply APCS.
++ * 05/19/2005 :	Adjust for boundary conditions.
++ */
++//#include <linux/config.h>
++#include <linux/linkage.h>
++#include <linux/init.h>
++#include <mach/hardware.h>
++#include <asm/page.h>
++#include "proc-macros.S"
++
++#define CACHE_DLINESIZE	   16
++#define CACHE_DSIZE	   16384
++#define CACHE_ILINESIZE	   16
++#define CACHE_ISIZE	   16384
++
++/*
++ *	initialize_cache_info()
++ *
++ *	Automatic detection of DSIZE, DLEN, ISIZE, ILEN variables according to 
++ *	system register CR0-1
++ *	Destroyed register: r0, r1, r2, r3, ip
++ */
++	.align
++ENTRY(fa_initialize_cache_info)
++	mov	r3, #1				@ r3 always = 1
++	adr	ip, __fa_cache_ilen
++	
++	mrc	p15, 0, r0, c0, c0, 1
++	/* ILEN */
++	and	r1, r0, #3			@ bits [1:0]
++	add	r1, r1, #3			@ cache line size is at least 8 bytes (2^3)
++	mov	r2, r3, lsl r1			@ r2 = 1<<r1
++	str	r2, [ip], #4
++	/* ISIZE */
++	mov	r1, r0, lsr #6			@ bits [8:6]
++	and	r1, r1, #7
++	add	r1, r1, #9			@ cache size is at least 512 bytes (2^9)
++	mov	r2, r3, lsl r1
++	str	r2, [ip], #4
++	/* DLEN */
++	mov	r1, r0, lsr #12
++	and	r1, r1, #3			@ bits [13:12]
++	add	r1, r1, #3			@ cache line size is at least 8 bytes (2^3)
++	mov	r2, r3, lsl r1			@ r2 = 1<<r1
++	str	r2, [ip], #4
++	/* DSIZE */
++	mov	r1, r0, lsr #18			@ bits [20:18]
++	and	r1, r1, #7
++	add	r1, r1, #9			@ cache size is at least 512 bytes (2^9)
++	mov	r2, r3, lsl r1
++	str	r2, [ip]
++	mov	pc, lr
++
++	/* Warning : Do not change the order ! Successive codes depends on this */
++	.align
++	.globl __fa_cache_ilen, __fa_cache_isize, __fa_cache_dlen, __fa_cache_dsize
++__fa_cache_ilen:
++	.word	0				@ instruction cache line length
++__fa_cache_isize:
++	.word	0				@ instruction cache size
++__fa_cache_dlen:
++	.word	0				@ data cahce line length	
++__fa_cache_dsize:
++	.word	0				@ data cache size
++
++/*
++ *	flush_user_cache_all()
++ *
++ *	Clean and invalidate all cache entries in a particular address
++ *	space.
++ */
++ENTRY(fa_flush_user_cache_all)
++	/* FALLTHROUGH */
++/*
++ *	flush_kern_cache_all()
++ *
++ *	Clean and invalidate the entire cache.
++ */
++ENTRY(fa_flush_kern_cache_all)
++	mov	ip, #0
++	
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
++#endif
++	
++__flush_whole_cache:
++	
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++	mov	ip, #0
++#  ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
++#  else
++	mcr	p15, 0, ip, c7,c14, 0		@ clean/invalidate D cache
++#  endif
++#endif /*CONFIG_CPU_DCACHE_DISABLE*/
++	
++#ifndef CONFIG_CPU_FA_WB_DISABLE	
++	mcr	p15, 0, ip, c7, c10, 4		@ drain write buffer
++#endif
++	
++#ifdef CONFIG_CPU_FA_BTB
++	mcr	p15, 0, ip, c7, c5, 6		@ invalidate BTB
++	nop
++	nop
++#endif
++	
++	mov	pc, lr
++
++/*
++ *	flush_user_cache_range(start, end, flags)
++ *
++ *	Invalidate a range of cache entries in the specified
++ *	address space.
++ *
++ *	- start - start address (inclusive, page aligned)
++ *	- end	- end address (exclusive, page aligned)
++ *	- flags	- vma_area_struct flags describing address space
++ */
++ENTRY(fa_flush_user_cache_range)
++	mov	ip, #0
++	sub	r3, r1, r0			@ calculate total size
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++	tst	r2, #VM_EXEC			@ executable region?
++	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
++#endif
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE	
++	cmp	r3, #CACHE_DSIZE		@ total size >= limit?
++	bhs	__flush_whole_cache		@ flush whole D cache
++
++1:
++	
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
++#else
++	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
++#endif
++	add	r0, r0, #CACHE_DLINESIZE
++	cmp	r0, r1
++	bls	1b
++#endif	/* CONFIG_CPU_DCACHE_DISABLE */
++	
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++	tst	r2, #VM_EXEC
++	mcreq	p15, 0, r4, c7, c10, 4		@ drain write buffer
++#endif
++
++#ifdef CONFIG_CPU_FA_BTB
++        tst     r2, #VM_EXEC
++	mov	ip, #0
++	mcrne	p15, 0, ip, c7, c5, 6		@ invalidate BTB
++	nop
++	nop
++#endif
++	mov	pc, lr
++
++/*
++ *	flush_kern_dcache_page(void *page)
++ *
++ *	Ensure no D cache aliasing occurs, either with itself or
++ *	the I cache
++ *
++ *	- addr	- page aligned address
++ */
++ENTRY(fa_flush_kern_dcache_page)
++	add	r1, r0, #PAGE_SZ
++	/* fall through */
++
++/*
++ *	coherent_kern_range(start, end)
++ *
++ *	Ensure coherency between the Icache and the Dcache in the
++ *	region described by start.  If you have non-snooping
++ *	Harvard caches, you need to implement this function.
++ *
++ *	- start  - virtual start address
++ *	- end	 - virtual end address
++ */
++ENTRY(fa_coherent_kern_range)
++	/* fall through */
++
++/*
++ *	coherent_user_range(start, end)
++ *
++ *	Ensure coherency between the Icache and the Dcache in the
++ *	region described by start.  If you have non-snooping
++ *	Harvard caches, you need to implement this function.
++ *
++ *	- start  - virtual start address
++ *	- end	 - virtual end address
++ */
++ENTRY(fa_coherent_user_range)
++	bic	r0, r0, #CACHE_DLINESIZE-1
++
++#if !(defined(CONFIG_CPU_DCACHE_DISABLE) && defined(CONFIG_CPU_ICACHE_DISABLE))
++1:
++#ifndef CONFIG_CPU_DCACHE_DISABLE	
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
++#else
++	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
++#endif
++#endif /* CONFIG_CPU_DCACHE_DISABLE */
++	
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++	mcr	p15, 0, r0, c7, c5, 1		@ invalidate I entry
++#endif
++	add	r0, r0, #CACHE_DLINESIZE
++	cmp	r0, r1
++	bls	1b				@ Luke Lee 05/19/2005 blo->bls	
++#endif /* !(defined(CONFIG_CPU_DCACHE_DISABLE) && defined(CONFIG_CPU_ICACHE_DISABLE)) */
++
++	mov	ip, #0
++#ifdef CONFIG_CPU_FA_BTB
++	mcr	p15, 0, ip, c7, c5, 6		@ invalidate BTB
++	nop
++	nop
++#endif
++
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
++#endif
++	
++	mov	pc, lr
++
++/*
++ *	dma_inv_range(start, end)
++ *
++ *	Invalidate (discard) the specified virtual address range.
++ *	May not write back any entries.  If 'start' or 'end'
++ *	are not cache line aligned, those lines must be written
++ *	back.
++ *
++ *	- start  - virtual start address
++ *	- end	 - virtual end address
++ */
++ENTRY(fa_dma_inv_range)
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE	
++
++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
++	tst	r0, #CACHE_DLINESIZE -1
++	bic	r0, r0, #CACHE_DLINESIZE -1
++	mcrne	p15, 0, r0, c7, c10, 1		@ clean boundary D entry
++	mcr	p15, 0, r1, c7, c10, 1		@ clean boundary D entry
++#else
++	bic	r0, r0, #CACHE_DLINESIZE -1	
++#endif
++	
++1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
++	add	r0, r0, #CACHE_DLINESIZE
++	cmp	r0, r1
++	bls	1b				@ Luke Lee 05/19/2005 blo->bls
++#endif /* CONFIG_CPU_DCACHE_DISABLE */
++
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++	mov	r0, #0
++	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
++#endif	
++	mov	pc, lr
++
++	
++	
++	
++	
++	
++	
++	
++/***** The following was lifted from 2.6.34 */   
++/*
++ *	flush_kern_dcache_area(void *addr, size_t size)
++ *
++ *	Ensure that the data held in the page kaddr is written back
++ *	to the page in question.
++ *
++ *	- addr	- kernel address
++ *	- size	- size of region
++ */
++ENTRY(fa_flush_kern_dcache_area)
++	add	r1, r0, r1
++1:	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D line
++	add	r0, r0, #CACHE_DLINESIZE
++	cmp	r0, r1
++	blo	1b
++	mov	r0, #0
++	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
++	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
++	mov	pc, lr
++   
++/*
++ *	dma_map_area(start, size, dir)
++ *	- start	- kernel virtual start address
++ *	- size	- size of region
++ *	- dir	- DMA direction
++ */
++ENTRY(fa_dma_map_area)
++	add	r1, r1, r0
++	cmp	r2, #DMA_TO_DEVICE
++	beq	fa_dma_clean_range
++	bcs	fa_dma_inv_range
++	b	fa_dma_flush_range
++ENDPROC(fa_dma_map_area)
++
++/*
++ *	dma_unmap_area(start, size, dir)
++ *	- start	- kernel virtual start address
++ *	- size	- size of region
++ *	- dir	- DMA direction
++ */
++ENTRY(fa_dma_unmap_area)
++	mov	pc, lr
++ENDPROC(fa_dma_unmap_area)   
++
++
++/********************/
++	
++	
++	
++	
++	
++	
++
++	
++	
++/*
++ *	dma_clean_range(start, end)
++ *
++ *	Clean (write back) the specified virtual address range.
++ *
++ *	- start  - virtual start address
++ *	- end	 - virtual end address
++ */
++ENTRY(fa_dma_clean_range)
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE	
++
++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
++	bic	r0, r0, #CACHE_DLINESIZE - 1
++1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
++	add	r0, r0, #CACHE_DLINESIZE
++	cmp	r0, r1
++	bls	1b				@ Luke Lee 05/19/2005 blo->bls
++
++#endif
++#endif /* CONFIG_CPU_DCACHE_DISABLE */
++
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++	mov	r0, #0	
++	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
++#endif	
++	mov	pc, lr
++
++/*
++ *	dma_flush_range(start, end)
++ *
++ *	Clean and invalidate the specified virtual address range.
++ *
++ *	- start  - virtual start address
++ *	- end	 - virtual end address
++ *
++ *	This is actually the same as fa_coherent_kern_range()
++ */
++	.globl	fa_dma_flush_range
++	.set	fa_dma_flush_range, fa_coherent_kern_range
++
++	__INITDATA
++
++	.type	fa_cache_fns, #object
++ENTRY(fa_cache_fns)
++	.long	fa_flush_kern_cache_all
++	.long	fa_flush_user_cache_all
++	.long	fa_flush_user_cache_range
++	.long	fa_coherent_kern_range
++	.long	fa_coherent_user_range
++	.long	fa_flush_kern_dcache_page
++	.long	fa_dma_inv_range
++	.long	fa_dma_clean_range
++	.long	fa_dma_flush_range
++	.size	fa_cache_fns, . - fa_cache_fns
++   
++
++   
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mm/copypage-fa.c linux-2.6.35.11-ts7500/arch/arm/mm/copypage-fa.c
+--- linux-2.6.35.11/arch/arm/mm/copypage-fa.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/copypage-fa.c	2011-03-14 11:18:24.000000000 -0400
+@@ -14,6 +14,7 @@
+ #include <linux/init.h>
+ #include <linux/highmem.h>
+ 
++#include <asm/page.h>
+ /*
+  * Faraday optimised copy_user_page
+  */
+diff -rupN linux-2.6.35.11/arch/arm/mm/dma-mapping.c linux-2.6.35.11-ts7500/arch/arm/mm/dma-mapping.c
+--- linux-2.6.35.11/arch/arm/mm/dma-mapping.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/dma-mapping.c	2011-03-14 11:18:24.000000000 -0400
+@@ -576,7 +576,8 @@ EXPORT_SYMBOL(dma_unmap_sg);
+  * @nents: number of buffers to map (returned from dma_map_sg)
+  * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+  */
+-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
++void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist 
++*sg,
+ 			int nents, enum dma_data_direction dir)
+ {
+ 	struct scatterlist *s;
+diff -rupN linux-2.6.35.11/arch/arm/mm/dma-mapping.c.orig linux-2.6.35.11-ts7500/arch/arm/mm/dma-mapping.c.orig
+--- linux-2.6.35.11/arch/arm/mm/dma-mapping.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/dma-mapping.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,618 @@
++/*
++ *  linux/arch/arm/mm/dma-mapping.c
++ *
++ *  Copyright (C) 2000-2004 Russell King
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  DMA uncached mapping support.
++ */
++#include <linux/module.h>
++#include <linux/mm.h>
++#include <linux/gfp.h>
++#include <linux/errno.h>
++#include <linux/list.h>
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/dma-mapping.h>
++
++#include <asm/memory.h>
++#include <asm/highmem.h>
++#include <asm/cacheflush.h>
++#include <asm/tlbflush.h>
++#include <asm/sizes.h>
++
++static u64 get_coherent_dma_mask(struct device *dev)
++{
++	u64 mask = ISA_DMA_THRESHOLD;
++
++	if (dev) {
++		mask = dev->coherent_dma_mask;
++
++		/*
++		 * Sanity check the DMA mask - it must be non-zero, and
++		 * must be able to be satisfied by a DMA allocation.
++		 */
++		if (mask == 0) {
++			dev_warn(dev, "coherent DMA mask is unset\n");
++			return 0;
++		}
++
++		if ((~mask) & ISA_DMA_THRESHOLD) {
++			dev_warn(dev, "coherent DMA mask %#llx is smaller "
++				 "than system GFP_DMA mask %#llx\n",
++				 mask, (unsigned long long)ISA_DMA_THRESHOLD);
++			return 0;
++		}
++	}
++
++	return mask;
++}
++
++/*
++ * Allocate a DMA buffer for 'dev' of size 'size' using the
++ * specified gfp mask.  Note that 'size' must be page aligned.
++ */
++static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gfp)
++{
++	unsigned long order = get_order(size);
++	struct page *page, *p, *e;
++	void *ptr;
++	u64 mask = get_coherent_dma_mask(dev);
++
++#ifdef CONFIG_DMA_API_DEBUG
++	u64 limit = (mask + 1) & ~mask;
++	if (limit && size >= limit) {
++		dev_warn(dev, "coherent allocation too big (requested %#x mask %#llx)\n",
++			size, mask);
++		return NULL;
++	}
++#endif
++
++	if (!mask)
++		return NULL;
++
++	if (mask < 0xffffffffULL)
++		gfp |= GFP_DMA;
++
++	page = alloc_pages(gfp, order);
++	if (!page)
++		return NULL;
++
++	/*
++	 * Now split the huge page and free the excess pages
++	 */
++	split_page(page, order);
++	for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++)
++		__free_page(p);
++
++	/*
++	 * Ensure that the allocated pages are zeroed, and that any data
++	 * lurking in the kernel direct-mapped region is invalidated.
++	 */
++	ptr = page_address(page);
++	memset(ptr, 0, size);
++	dmac_flush_range(ptr, ptr + size);
++	outer_flush_range(__pa(ptr), __pa(ptr) + size);
++
++	return page;
++}
++
++/*
++ * Free a DMA buffer.  'size' must be page aligned.
++ */
++static void __dma_free_buffer(struct page *page, size_t size)
++{
++	struct page *e = page + (size >> PAGE_SHIFT);
++
++	while (page < e) {
++		__free_page(page);
++		page++;
++	}
++}
++
++#ifdef CONFIG_MMU
++/* Sanity check size */
++#if (CONSISTENT_DMA_SIZE % SZ_2M)
++#error "CONSISTENT_DMA_SIZE must be multiple of 2MiB"
++#endif
++
++#define CONSISTENT_OFFSET(x)	(((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
++#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
++#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
++
++/*
++ * These are the page tables (2MB each) covering uncached, DMA consistent allocations
++ */
++static pte_t *consistent_pte[NUM_CONSISTENT_PTES];
++
++#include "vmregion.h"
++
++static struct arm_vmregion_head consistent_head = {
++	.vm_lock	= __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock),
++	.vm_list	= LIST_HEAD_INIT(consistent_head.vm_list),
++	.vm_start	= CONSISTENT_BASE,
++	.vm_end		= CONSISTENT_END,
++};
++
++#ifdef CONFIG_HUGETLB_PAGE
++#error ARM Coherent DMA allocator does not (yet) support huge TLB
++#endif
++
++/*
++ * Initialise the consistent memory allocation.
++ */
++static int __init consistent_init(void)
++{
++	int ret = 0;
++	pgd_t *pgd;
++	pmd_t *pmd;
++	pte_t *pte;
++	int i = 0;
++	u32 base = CONSISTENT_BASE;
++
++	do {
++		pgd = pgd_offset(&init_mm, base);
++		pmd = pmd_alloc(&init_mm, pgd, base);
++		if (!pmd) {
++			printk(KERN_ERR "%s: no pmd tables\n", __func__);
++			ret = -ENOMEM;
++			break;
++		}
++		WARN_ON(!pmd_none(*pmd));
++
++		pte = pte_alloc_kernel(pmd, base);
++		if (!pte) {
++			printk(KERN_ERR "%s: no pte tables\n", __func__);
++			ret = -ENOMEM;
++			break;
++		}
++
++		consistent_pte[i++] = pte;
++		base += (1 << PGDIR_SHIFT);
++	} while (base < CONSISTENT_END);
++
++	return ret;
++}
++
++core_initcall(consistent_init);
++
++static void *
++__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
++{
++	struct arm_vmregion *c;
++
++	if (!consistent_pte[0]) {
++		printk(KERN_ERR "%s: not initialised\n", __func__);
++		dump_stack();
++		return NULL;
++	}
++
++	/*
++	 * Allocate a virtual address in the consistent mapping region.
++	 */
++	c = arm_vmregion_alloc(&consistent_head, size,
++			    gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
++	if (c) {
++		pte_t *pte;
++		int idx = CONSISTENT_PTE_INDEX(c->vm_start);
++		u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
++
++		pte = consistent_pte[idx] + off;
++		c->vm_pages = page;
++
++		do {
++			BUG_ON(!pte_none(*pte));
++
++			set_pte_ext(pte, mk_pte(page, prot), 0);
++			page++;
++			pte++;
++			off++;
++			if (off >= PTRS_PER_PTE) {
++				off = 0;
++				pte = consistent_pte[++idx];
++			}
++		} while (size -= PAGE_SIZE);
++
++		return (void *)c->vm_start;
++	}
++	return NULL;
++}
++
++static void __dma_free_remap(void *cpu_addr, size_t size)
++{
++	struct arm_vmregion *c;
++	unsigned long addr;
++	pte_t *ptep;
++	int idx;
++	u32 off;
++
++	c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr);
++	if (!c) {
++		printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
++		       __func__, cpu_addr);
++		dump_stack();
++		return;
++	}
++
++	if ((c->vm_end - c->vm_start) != size) {
++		printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
++		       __func__, c->vm_end - c->vm_start, size);
++		dump_stack();
++		size = c->vm_end - c->vm_start;
++	}
++
++	idx = CONSISTENT_PTE_INDEX(c->vm_start);
++	off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
++	ptep = consistent_pte[idx] + off;
++	addr = c->vm_start;
++	do {
++		pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
++
++		ptep++;
++		addr += PAGE_SIZE;
++		off++;
++		if (off >= PTRS_PER_PTE) {
++			off = 0;
++			ptep = consistent_pte[++idx];
++		}
++
++		if (pte_none(pte) || !pte_present(pte))
++			printk(KERN_CRIT "%s: bad page in kernel page table\n",
++			       __func__);
++	} while (size -= PAGE_SIZE);
++
++	flush_tlb_kernel_range(c->vm_start, c->vm_end);
++
++	arm_vmregion_free(&consistent_head, c);
++}
++
++#else	/* !CONFIG_MMU */
++
++#define __dma_alloc_remap(page, size, gfp, prot)	page_address(page)
++#define __dma_free_remap(addr, size)			do { } while (0)
++
++#endif	/* CONFIG_MMU */
++
++static void *
++__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
++	    pgprot_t prot)
++{
++	struct page *page;
++	void *addr;
++
++	*handle = ~0;
++	size = PAGE_ALIGN(size);
++
++	page = __dma_alloc_buffer(dev, size, gfp);
++	if (!page)
++		return NULL;
++
++	if (!arch_is_coherent())
++		addr = __dma_alloc_remap(page, size, gfp, prot);
++	else
++		addr = page_address(page);
++
++	if (addr)
++		*handle = page_to_dma(dev, page);
++
++	return addr;
++}
++
++/*
++ * Allocate DMA-coherent memory space and return both the kernel remapped
++ * virtual and bus address for that space.
++ */
++void *
++dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
++{
++	void *memory;
++
++	if (dma_alloc_from_coherent(dev, size, handle, &memory))
++		return memory;
++
++	return __dma_alloc(dev, size, handle, gfp,
++			   pgprot_dmacoherent(pgprot_kernel));
++}
++EXPORT_SYMBOL(dma_alloc_coherent);
++
++/*
++ * Allocate a writecombining region, in much the same way as
++ * dma_alloc_coherent above.
++ */
++void *
++dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
++{
++	return __dma_alloc(dev, size, handle, gfp,
++			   pgprot_writecombine(pgprot_kernel));
++}
++EXPORT_SYMBOL(dma_alloc_writecombine);
++
++static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
++		    void *cpu_addr, dma_addr_t dma_addr, size_t size)
++{
++	int ret = -ENXIO;
++#ifdef CONFIG_MMU
++	unsigned long user_size, kern_size;
++	struct arm_vmregion *c;
++
++	user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
++
++	c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
++	if (c) {
++		unsigned long off = vma->vm_pgoff;
++
++		kern_size = (c->vm_end - c->vm_start) >> PAGE_SHIFT;
++
++		if (off < kern_size &&
++		    user_size <= (kern_size - off)) {
++			ret = remap_pfn_range(vma, vma->vm_start,
++					      page_to_pfn(c->vm_pages) + off,
++					      user_size << PAGE_SHIFT,
++					      vma->vm_page_prot);
++		}
++	}
++#endif	/* CONFIG_MMU */
++
++	return ret;
++}
++
++int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
++		      void *cpu_addr, dma_addr_t dma_addr, size_t size)
++{
++	vma->vm_page_prot = pgprot_dmacoherent(vma->vm_page_prot);
++	return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
++}
++EXPORT_SYMBOL(dma_mmap_coherent);
++
++int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
++			  void *cpu_addr, dma_addr_t dma_addr, size_t size)
++{
++	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
++	return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
++}
++EXPORT_SYMBOL(dma_mmap_writecombine);
++
++/*
++ * free a page as defined by the above mapping.
++ * Must not be called with IRQs disabled.
++ */
++void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
++{
++	WARN_ON(irqs_disabled());
++
++	if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
++		return;
++
++	size = PAGE_ALIGN(size);
++
++	if (!arch_is_coherent())
++		__dma_free_remap(cpu_addr, size);
++
++	__dma_free_buffer(dma_to_page(dev, handle), size);
++}
++EXPORT_SYMBOL(dma_free_coherent);
++
++/*
++ * Make an area consistent for devices.
++ * Note: Drivers should NOT use this function directly, as it will break
++ * platforms with CONFIG_DMABOUNCE.
++ * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
++ */
++void ___dma_single_cpu_to_dev(const void *kaddr, size_t size,
++	enum dma_data_direction dir)
++{
++	unsigned long paddr;
++
++	BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
++
++	dmac_map_area(kaddr, size, dir);
++
++	paddr = __pa(kaddr);
++	if (dir == DMA_FROM_DEVICE) {
++		outer_inv_range(paddr, paddr + size);
++	} else {
++		outer_clean_range(paddr, paddr + size);
++	}
++	/* FIXME: non-speculating: flush on bidirectional mappings? */
++}
++EXPORT_SYMBOL(___dma_single_cpu_to_dev);
++
++void ___dma_single_dev_to_cpu(const void *kaddr, size_t size,
++	enum dma_data_direction dir)
++{
++	BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
++
++	/* FIXME: non-speculating: not required */
++	/* don't bother invalidating if DMA to device */
++	if (dir != DMA_TO_DEVICE) {
++		unsigned long paddr = __pa(kaddr);
++		outer_inv_range(paddr, paddr + size);
++	}
++
++	dmac_unmap_area(kaddr, size, dir);
++}
++EXPORT_SYMBOL(___dma_single_dev_to_cpu);
++
++static void dma_cache_maint_page(struct page *page, unsigned long offset,
++	size_t size, enum dma_data_direction dir,
++	void (*op)(const void *, size_t, int))
++{
++	/*
++	 * A single sg entry may refer to multiple physically contiguous
++	 * pages.  But we still need to process highmem pages individually.
++	 * If highmem is not configured then the bulk of this loop gets
++	 * optimized out.
++	 */
++	size_t left = size;
++	do {
++		size_t len = left;
++		void *vaddr;
++
++		if (PageHighMem(page)) {
++			if (len + offset > PAGE_SIZE) {
++				if (offset >= PAGE_SIZE) {
++					page += offset / PAGE_SIZE;
++					offset %= PAGE_SIZE;
++				}
++				len = PAGE_SIZE - offset;
++			}
++			vaddr = kmap_high_get(page);
++			if (vaddr) {
++				vaddr += offset;
++				op(vaddr, len, dir);
++				kunmap_high(page);
++			} else if (cache_is_vipt()) {
++				pte_t saved_pte;
++				vaddr = kmap_high_l1_vipt(page, &saved_pte);
++				op(vaddr + offset, len, dir);
++				kunmap_high_l1_vipt(page, saved_pte);
++			}
++		} else {
++			vaddr = page_address(page) + offset;
++			op(vaddr, len, dir);
++		}
++		offset = 0;
++		page++;
++		left -= len;
++	} while (left);
++}
++
++void ___dma_page_cpu_to_dev(struct page *page, unsigned long off,
++	size_t size, enum dma_data_direction dir)
++{
++	unsigned long paddr;
++
++	dma_cache_maint_page(page, off, size, dir, dmac_map_area);
++
++	paddr = page_to_phys(page) + off;
++	if (dir == DMA_FROM_DEVICE) {
++		outer_inv_range(paddr, paddr + size);
++	} else {
++		outer_clean_range(paddr, paddr + size);
++	}
++	/* FIXME: non-speculating: flush on bidirectional mappings? */
++}
++EXPORT_SYMBOL(___dma_page_cpu_to_dev);
++
++void ___dma_page_dev_to_cpu(struct page *page, unsigned long off,
++	size_t size, enum dma_data_direction dir)
++{
++	unsigned long paddr = page_to_phys(page) + off;
++
++	/* FIXME: non-speculating: not required */
++	/* don't bother invalidating if DMA to device */
++	if (dir != DMA_TO_DEVICE)
++		outer_inv_range(paddr, paddr + size);
++
++	dma_cache_maint_page(page, off, size, dir, dmac_unmap_area);
++}
++EXPORT_SYMBOL(___dma_page_dev_to_cpu);
++
++/**
++ * dma_map_sg - map a set of SG buffers for streaming mode DMA
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @sg: list of buffers
++ * @nents: number of buffers to map
++ * @dir: DMA transfer direction
++ *
++ * Map a set of buffers described by scatterlist in streaming mode for DMA.
++ * This is the scatter-gather version of the dma_map_single interface.
++ * Here the scatter gather list elements are each tagged with the
++ * appropriate dma address and length.  They are obtained via
++ * sg_dma_{address,length}.
++ *
++ * Device ownership issues as mentioned for dma_map_single are the same
++ * here.
++ */
++int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
++		enum dma_data_direction dir)
++{
++	struct scatterlist *s;
++	int i, j;
++
++	for_each_sg(sg, s, nents, i) {
++		s->dma_address = dma_map_page(dev, sg_page(s), s->offset,
++						s->length, dir);
++		if (dma_mapping_error(dev, s->dma_address))
++			goto bad_mapping;
++	}
++	return nents;
++
++ bad_mapping:
++	for_each_sg(sg, s, i, j)
++		dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
++	return 0;
++}
++EXPORT_SYMBOL(dma_map_sg);
++
++/**
++ * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @sg: list of buffers
++ * @nents: number of buffers to unmap (returned from dma_map_sg)
++ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
++ *
++ * Unmap a set of streaming mode DMA translations.  Again, CPU access
++ * rules concerning calls here are the same as for dma_unmap_single().
++ */
++void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
++		enum dma_data_direction dir)
++{
++	struct scatterlist *s;
++	int i;
++
++	for_each_sg(sg, s, nents, i)
++		dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
++}
++EXPORT_SYMBOL(dma_unmap_sg);
++
++/**
++ * dma_sync_sg_for_cpu
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @sg: list of buffers
++ * @nents: number of buffers to map (returned from dma_map_sg)
++ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
++ */
++void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
++			int nents, enum dma_data_direction dir)
++{
++	struct scatterlist *s;
++	int i;
++
++	for_each_sg(sg, s, nents, i) {
++		if (!dmabounce_sync_for_cpu(dev, sg_dma_address(s), 0,
++					    sg_dma_len(s), dir))
++			continue;
++
++		__dma_page_dev_to_cpu(sg_page(s), s->offset,
++				      s->length, dir);
++	}
++}
++EXPORT_SYMBOL(dma_sync_sg_for_cpu);
++
++/**
++ * dma_sync_sg_for_device
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @sg: list of buffers
++ * @nents: number of buffers to map (returned from dma_map_sg)
++ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
++ */
++void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
++			int nents, enum dma_data_direction dir)
++{
++	struct scatterlist *s;
++	int i;
++
++	for_each_sg(sg, s, nents, i) {
++		if (!dmabounce_sync_for_device(dev, sg_dma_address(s), 0,
++					sg_dma_len(s), dir))
++			continue;
++
++		__dma_page_cpu_to_dev(sg_page(s), s->offset,
++				      s->length, dir);
++	}
++}
++EXPORT_SYMBOL(dma_sync_sg_for_device);
+diff -rupN linux-2.6.35.11/arch/arm/mm/flush.c linux-2.6.35.11-ts7500/arch/arm/mm/flush.c
+--- linux-2.6.35.11/arch/arm/mm/flush.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/flush.c	2011-03-14 11:18:24.000000000 -0400
+@@ -290,7 +290,7 @@ void __flush_anon_page(struct vm_area_st
+ 		 * userspace address only.
+ 		 */
+ 		flush_pfn_alias(pfn, vmaddr);
+-		__flush_icache_all();
++		__flush_icache_all(); 
+ 	}
+ 
+ 	/*
+diff -rupN linux-2.6.35.11/arch/arm/mm/Kconfig linux-2.6.35.11-ts7500/arch/arm/mm/Kconfig
+--- linux-2.6.35.11/arch/arm/mm/Kconfig	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -142,6 +142,54 @@ config CPU_ARM922T
+ 	  Say Y if you want support for the ARM922T processor.
+ 	  Otherwise, say N.
+ 
++# FA520/FA526/FA626
++
++choice
++	prompt "Faraday processor (ARM9 compatible) type"
++	default CPU_FA526
++	depends on ARCH_STR9100 || ARCH_STR8100
++
++#config CPU_FA520
++#       bool  "FA520 processor"
++#       depends on ARCH_STR9100 || ARCH_STR8100
++#       select CPU_32v4
++#       select CPU_ABRT_EV4
++#       select CPU_CACHE_FA
++#       select CPU_CACHE_VIVT
++#       select CPU_COPY_V4WB
++#       select CPU_TLB_FA
++#       help
++#         //TODO: FA520 help info
++
++config CPU_FA526
++	bool  "FA526 processor"
++	depends on ARCH_STR9100 || ARCH_STR8100
++	select CPU_32v4
++   select CPU_PABRT_LEGACY
++	select CPU_ABRT_EV4
++   select CPU_CP15_MMU
++   select CPU_CACHE_FA
++   select CPU_CACHE_VIVT
++	select CPU_COPY_FA if MMU
++	select CPU_TLB_FA if MMU
++	help
++	  //TODO: FA526 help info
++
++#config CPU_FA626
++#       bool  "FA626 processor"
++#       depends on ARCH_STR9100 || ARCH_STR8100
++#       select CPU_32v4
++#       select CPU_ABRT_EV4
++#       select CPU_CACHE_FA
++#       select CPU_CACHE_VIPT
++#       select CPU_COPY_V4WB
++#       select CPU_TLB_FA
++#       help
++#         //TODO: FA626 help info
++
++endchoice
++     
++     
+ # ARM925T
+ config CPU_ARM925T
+  	bool "Support ARM925T processor" if ARCH_OMAP1
+@@ -180,22 +228,22 @@ config CPU_ARM926T
+ 	  Otherwise, say N.
+ 
+ # FA526
+-config CPU_FA526
+-	bool
+-	select CPU_32v4
+-	select CPU_ABRT_EV4
+-	select CPU_PABRT_LEGACY
+-	select CPU_CACHE_VIVT
+-	select CPU_CP15_MMU
+-	select CPU_CACHE_FA
+-	select CPU_COPY_FA if MMU
+-	select CPU_TLB_FA if MMU
+-	help
+-	  The FA526 is a version of the ARMv4 compatible processor with
+-	  Branch Target Buffer, Unified TLB and cache line size 16.
+-
+-	  Say Y if you want support for the FA526 processor.
+-	  Otherwise, say N.
++#config CPU_FA526
++#	bool
++#	select CPU_32v4
++#	select CPU_ABRT_EV4
++#	select CPU_PABRT_LEGACY
++#	select CPU_CACHE_VIVT
++#	select CPU_CP15_MMU
++#	select CPU_CACHE_FA
++#	select CPU_COPY_FA if MMU
++#	select CPU_TLB_FA if MMU
++#	help
++#	  The FA526 is a version of the ARMv4 compatible processor with
++#	  Branch Target Buffer, Unified TLB and cache line size 16.
++#
++#	  Say Y if you want support for the FA526 processor.
++#	  Otherwise, say N.
+ 
+ # ARM940T
+ config CPU_ARM940T
+@@ -566,6 +614,7 @@ config CPU_TLB_FA
+ 	  and invalidate instruction cache entry. Branch target buffer is
+ 	  also supported.
+ 
++      
+ config CPU_TLB_V6
+ 	bool
+ 
+@@ -664,14 +713,16 @@ config CPU_HIGH_VECTOR
+ 
+ config CPU_ICACHE_DISABLE
+ 	bool "Disable I-Cache (I-bit)"
+-	depends on CPU_CP15 && !(CPU_ARM610 || CPU_ARM710 || CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3)
++#	depends on CPU_CP15 && !(CPU_ARM610 || CPU_ARM710 || CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3 || CPU_FA520 || CPU_FA526 || CPU_FA626)
++   depends on CPU_CP15
+ 	help
+ 	  Say Y here to disable the processor instruction cache. Unless
+ 	  you have a reason not to or are unsure, say N.
+ 
+ config CPU_DCACHE_DISABLE
+ 	bool "Disable D-Cache (C-bit)"
+-	depends on CPU_CP15
++#	depends on CPU_CP15 && !(CPU_FA520 || CPU_FA526 || CPU_FA626)
++ 	depends on CPU_CP15  
+ 	help
+ 	  Say Y here to disable the processor data cache. Unless
+ 	  you have a reason not to or are unsure, say N.
+@@ -697,6 +748,19 @@ config CPU_DCACHE_WRITETHROUGH
+ 	  Say Y here to use the data cache in writethrough mode. Unless you
+ 	  specifically require this or are unsure, say N.
+ 
++config CPU_FA_BTB
++ 	bool "BTB support (EXPERIMENTAL)"
++ 	depends on CPU_FA520 || CPU_FA526 || CPU_FA626
++ 	default y
++ 	help
++ 	//TODO: FA BTB
++
++config CPU_FA_WB_DISABLE
++ 	bool "Disable write buffer (EXPERIMENTAL)"
++ 	depends on CPU_FA520 || CPU_FA526 || CPU_FA626
++ 	help
++ 	//TODO: FA write buffer     
++     
+ config CPU_CACHE_ROUND_ROBIN
+ 	bool "Round robin I and D cache replacement algorithm"
+ 	depends on (CPU_ARM926T || CPU_ARM946E || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE)
+diff -rupN linux-2.6.35.11/arch/arm/mm/proc-fa526.S linux-2.6.35.11-ts7500/arch/arm/mm/proc-fa526.S
+--- linux-2.6.35.11/arch/arm/mm/proc-fa526.S	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/proc-fa526.S	2011-03-14 11:18:24.000000000 -0400
+@@ -1,3 +1,4 @@
++#if (1)
+ /*
+  *  linux/arch/arm/mm/proc-fa526.S: MMU functions for FA526
+  *
+@@ -138,6 +139,7 @@ ENTRY(cpu_fa526_set_pte_ext)
+ #endif
+ 	mov	pc, lr
+ 
++   
+ 	__INIT
+ 
+ 	.type	__fa526_setup, #function
+@@ -246,3 +248,428 @@ __fa526_proc_info:
+ 	.long	fa_user_fns
+ 	.long	fa_cache_fns
+ 	.size	__fa526_proc_info, . - __fa526_proc_info
++   
++#else
++/*
++ *  linux/arch/arm/mm/proc-fa526.S: MMU functions for FA526
++ *
++ *  Copyright (C) 2005 Faraday Corp.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ *
++ * These are the low level assembler for performing cache and TLB
++ * functions on the fa526.
++ *
++ *  Written by : Luke Lee
++ */
++#include <linux/linkage.h>
++//#include <linux/config.h>
++#include <linux/init.h>
++#include <asm/assembler.h>
++#include <asm/pgtable.h>
++/* scott.test
++#include <asm/procinfo.h>
++*/
++#include <mach/hardware.h>
++#include <asm/page.h>
++#include <asm/ptrace.h>
++#include <asm/system.h>
++#include "proc-macros.S"
++
++#define CACHE_DLINESIZE	   16
++
++	.text
++/*
++ * cpu_fa526_proc_init()
++ */
++ENTRY(cpu_fa526_proc_init)
++	/* MMU is already ON here, ICACHE, DCACHE conditionally disabled */
++
++        mov     r0, #1
++	nop
++	nop
++        mcr     p15, 0, r0, c1, c1, 0		@ turn-on ECR
++	nop
++	nop
++
++	mrc	p15, 0, r0, c1, c0, 0		@ read ctrl register
++
++#ifdef CONFIG_CPU_FA_BTB
++	orr	r0, r0, #CR_Z
++#else
++	bic	r0, r0, #CR_Z	
++#endif
++#ifdef CONFIG_CPU_FA_WB_DISABLE
++	mov	r1, #0
++	mcr	p15, 0, r1, c7, c10, 4		@ drain write buffer
++	nop
++	nop
++	bic	r0, r0, #CR_W
++#else
++	orr	r0, r0, #CR_W
++#endif
++#ifdef CONFIG_CPU_DCACHE_DISABLE
++	bic	r0, r0, #CR_C
++#else
++	orr	r0, r0, #CR_C	
++#endif
++#ifdef CONFIG_CPU_ICACHE_DISABLE
++	bic	r0, r0, #CR_I
++#else
++	orr	r0, r0, #CR_I	
++#endif
++	
++	nop
++	nop
++    	mcr	p15, 0, r0, c1, c0, 0
++	nop
++	nop
++
++	mov	r5, lr
++	bl	fa_initialize_cache_info	@ destroy r0~r4	
++	mov	pc, r5				@ return
++
++
++/*
++ * cpu_fa526_proc_fin()
++ */
++ENTRY(cpu_fa526_proc_fin)
++	stmfd	sp!, {lr}
++	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
++	msr	cpsr_c, ip
++
++	bl	fa_flush_kern_cache_all
++	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
++	bic	r0, r0, #0x1000			@ ...i............
++	bic	r0, r0, #0x000e			@ ............wca.
++	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
++
++	nop
++	nop
++	ldmfd	sp!, {pc}
++
++/*
++ * cpu_fa526_reset(loc)
++ *
++ * Perform a soft reset of the system.  Put the CPU into the
++ * same state as it would be if it had been reset, and branch
++ * to what would be the reset vector.
++ *
++ * loc: location to jump to for soft reset
++ */
++	.align	4
++ENTRY(cpu_fa526_reset)
++	mov	ip, #0
++	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
++#ifndef CONFIG_CPU_FA_WB_DISABLE	
++	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
++#endif	
++	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
++	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
++	bic	ip, ip, #0x000f			@ ............wcam
++	bic	ip, ip, #0x1100			@ ...i...s........
++
++	bic	ip, ip, #0x0800			@ BTB off
++	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
++	nop
++	nop
++	mov	pc, r0
++
++/*
++ * cpu_fa526_do_idle()
++ */
++	.align	4
++ENTRY(cpu_fa526_do_idle)
++
++#ifdef CONFIG_CPU_FA_IDLE
++	nop
++	nop
++	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt (IDLE mode)
++#endif
++	mov	pc, lr
++
++
++ENTRY(cpu_fa526_dcache_clean_area)
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
++1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
++	add	r0, r0, #CACHE_DLINESIZE
++	subs	r1, r1, #CACHE_DLINESIZE
++	bhi	1b
++#endif
++#endif	
++	mov	pc, lr
++	
++
++/* =============================== PageTable ============================== */
++
++/*
++ * cpu_fa526_switch_mm(pgd)
++ *
++ * Set the translation base pointer to be as described by pgd.
++ *
++ * pgd: new page tables
++ */
++	.align	4
++
++	.globl	fault_address
++fault_address:	
++	.long	0
++	
++ENTRY(cpu_fa526_switch_mm)
++
++	mov	ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE	
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
++#else
++	mcr	p15, 0, ip, c7, c14, 0		@ Clean and invalidate whole DCache
++#endif
++#endif /*CONFIG_CPU_DCACHE_DISABLE*/
++	
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
++#endif	
++
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
++#endif	
++
++#ifdef CONFIG_CPU_FA_BTB
++	mcr	p15, 0, ip, c7, c5, 6		@ invalidate BTB since mm changed
++	nop
++	nop
++#endif
++	bic	r0, r0, #0xff			@ clear bits [7:0]
++	bic	r0, r0, #0x3f00			@ clear bits [13:8]
++	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
++	mcr	p15, 0, ip, c8, c7, 0		@ invalidate UTLB
++	nop
++	nop
++	mov	pc, lr
++
++/*
++ * cpu_fa526_set_pte_ext(ptep, pte, ext)
++ *
++ * Set a PTE and flush it out
++ */
++	.align	4
++ENTRY(cpu_fa526_set_pte_ext)
++	str	r1, [r0], #-2048		@ linux version
++	
++	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
++
++	bic	r2, r1, #PTE_SMALL_AP_MASK
++	bic	r2, r2, #PTE_TYPE_MASK
++	orr	r2, r2, #PTE_TYPE_SMALL
++
++	tst	r1, #L_PTE_USER			@ User?
++	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
++
++	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
++	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
++
++	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
++	movne	r2, #0
++
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++	eor	r3, r2, #0x0a			@ C & small page?  1010
++	tst	r3, #0x0b			@		   1011
++	biceq	r2, r2, #4
++#endif
++	str	r2, [r0]			@ hardware version
++
++	mov	r2, #0
++	mcr	p15, 0, r2, c7, c10, 0		@ clean D cache	all
++	
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++	mcr	p15, 0, r2, c7, c10, 4		@ drain WB
++#endif
++#ifdef CONFIG_CPU_FA_BTB
++	mcr	p15, 0, r2, c7, c5, 6		@ invalidate BTB
++	nop
++	nop
++#endif
++	mov	pc, lr
++	
++   
++#ifdef CONFIG_DEBUG_LL
++str_fa526_setup: .asciz "str_fa526_setup\n"   
++str_fa526_setup_done: .asciz "str_fa526_setup_done\n"
++.align 4
++#endif   
++	__INIT
++
++	.type	__fa526_setup, #function
++__fa526_setup:
++#ifdef CONFIG_DEBUG_LL
++   adr	r0, str_fa526_setup
++	bl	printascii
++#endif
++	/* On return of this routine, r0 must carry correct flags for CFG register */	
++	mov	r0, #0
++	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
++	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
++	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
++
++	mcr	p15, 0, r0, c7, c5, 5		@ invalidate IScratchpad RAM
++
++        mov     r0, #1
++        mcr     p15, 0, r0, c1, c1, 0		@ turn-on ECR
++
++	mrc	p15, 0, r0, c9, c1, 0		@ DScratchpad
++	bic	r0, r0, #1
++	mcr	p15, 0, r0, c9, c1, 0
++	mrc	p15, 0, r0, c9, c1, 1		@ IScratchpad
++	bic	r0, r0, #1
++	mcr	p15, 0, r0, c9, c1, 1
++
++	mov	r0, #0
++	mcr	p15, 0, r0, c1, c1, 0		@ turn-off ECR
++	
++#ifdef CONFIG_CPU_FA_BTB
++	mcr	p15, 0, r0, c7, c5, 6		@ invalidate BTB All
++	nop
++	nop
++#endif		
++		
++	mov	r0, #0x1f			@ Domains 0, 1 = manager, 2 = client
++	mcr	p15, 0, r0, c3, c0		@ load domain access register
++	
++	mrc	p15, 0, r0, c1, c0		@ get control register v4
++	ldr	r5, fa526_cr1_clear
++	bic	r0, r0, r5
++	ldr	r5, fa526_cr1_set
++	orr	r0, r0, r5
++
++#ifdef CONFIG_CPU_FA_BTB
++	orr	r0, r0, #CR_Z
++#else
++	bic	r0, r0, #CR_Z	
++#endif
++#ifdef CONFIG_CPU_FA_WB_DISABLE
++	mov	r12, #0
++	mcr	p15, 0, r12, c7, c10, 4		@ drain write buffer
++	nop
++	nop
++	bic	r0, r0, #CR_W			@ .... .... .... 1...
++#else
++	orr	r0, r0, #CR_W
++#endif
++
++#ifdef CONFIG_DEBUG_LL
++   adr	r0, str_fa526_setup_done
++	bl	printascii
++#endif
++
++	mov	pc, lr
++	.size	__fa526_setup, . - __fa526_setup
++
++	/*
++	 * .RVI ZFRS BLDP WCAM
++	 * ..11 0001 .111 1101
++	 * 
++	 */
++	.type	fa526_cr1_clear, #object
++	.type	fa526_cr1_set, #object
++fa526_cr1_clear:
++	.word	0x3f3f
++fa526_cr1_set:
++	.word	0x317D
++
++	__INITDATA
++
++/*
++ * Purpose : Function pointers used to access above functions - all calls
++ *	     come through these
++ */
++	.type	fa526_processor_functions, #object
++fa526_processor_functions:
++	.word	v4_early_abort
++	.word	legacy_pabort            @ Ian added	
++	.word	cpu_fa526_proc_init
++	.word	cpu_fa526_proc_fin
++	.word	cpu_fa526_reset
++	.word   cpu_fa526_do_idle
++	.word	cpu_fa526_dcache_clean_area
++	.word	cpu_fa526_switch_mm
++	.word	cpu_fa526_set_pte_ext
++	.size	fa526_processor_functions, . - fa526_processor_functions
++
++	.section ".rodata"
++
++	.type	cpu_arch_name, #object
++cpu_arch_name:
++	.asciz	"armv4"
++	.size	cpu_arch_name, . - cpu_arch_name
++
++	.type	cpu_elf_name, #object
++cpu_elf_name:
++	.asciz	"v4"
++	.size	cpu_elf_name, . - cpu_elf_name
++
++	.type	cpu_fa526_name, #object
++cpu_fa526_name:
++	.ascii	"FA526"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++	.ascii	"i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++	.ascii	"d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++	.ascii	"(wt)"
++#else
++	.ascii	"(wb)"
++#endif
++#endif
++	.ascii	"\0"
++	.size	cpu_fa526_name, . - cpu_fa526_name
++
++	.align
++
++	.section ".proc.info.init", #alloc, #execinstr
++
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++#define __PMD_SECT_BUFFERABLE	0
++#else
++#define __PMD_SECT_BUFFERABLE	PMD_SECT_BUFFERABLE
++#endif
++
++	.type	__fa526_proc_info,#object
++__fa526_proc_info:
++	.long	0x66015261
++	.long	0xff01fff1
++	.long   PMD_TYPE_SECT | \
++		__PMD_SECT_BUFFERABLE | \
++		PMD_SECT_CACHEABLE | \
++		PMD_BIT4 | \
++		PMD_SECT_AP_WRITE | \
++		PMD_SECT_AP_READ
++	.long   PMD_TYPE_SECT | \
++		PMD_SECT_AP_WRITE | \
++		PMD_SECT_AP_READ
++	b	__fa526_setup
++	.long	cpu_arch_name
++	.long	cpu_elf_name
++	.long	HWCAP_SWP | HWCAP_HALF
++	.long	cpu_fa526_name
++	.long	fa526_processor_functions
++	.long	fa_tlb_fns
++	.long	fa_user_fns
++	.long	fa_cache_fns
++	.size	__fa526_proc_info, . - __fa526_proc_info
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mm/proc-fa526.S.orig linux-2.6.35.11-ts7500/arch/arm/mm/proc-fa526.S.orig
+--- linux-2.6.35.11/arch/arm/mm/proc-fa526.S.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/proc-fa526.S.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,248 @@
++/*
++ *  linux/arch/arm/mm/proc-fa526.S: MMU functions for FA526
++ *
++ *  Written by : Luke Lee
++ *  Copyright (C) 2005 Faraday Corp.
++ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas at 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 at 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 at intel.com>
++  e1000-devel Mailing List <e1000-devel at 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 at 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 at 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 at 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 at 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 at 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 at 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 at starsemi.com>
++#
++################################################################################
++
++#
++# Makefile for the Star GSW ethernet driver
++#
++
++obj-$(CONFIG_STAR_NIC) += star_nic_module.o
++star_nic_module-objs := star_nic.o
++
+diff -rupN linux-2.6.35.11/drivers/net/str8100/star_nic.c linux-2.6.35.11-ts7500/drivers/net/str8100/star_nic.c
+--- linux-2.6.35.11/drivers/net/str8100/star_nic.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str8100/star_nic.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,3070 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/kernel.h>
++#include <linux/bootmem.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/fcntl.h>
++#include <linux/interrupt.h>
++#include <linux/ptrace.h>
++#include <linux/ioport.h>
++#include <linux/in.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++#include <asm/bitops.h>
++#include <asm/irq.h>		// 2006.03.22 richliu add list include file
++#include <asm/io.h>
++#include <asm/hardware.h>
++#include <linux/pci.h>
++#include <linux/errno.h>
++#include <linux/delay.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/ip.h>
++#include <linux/if_ether.h>
++#include <linux/icmp.h>
++#include <linux/udp.h>
++#include <linux/tcp.h>
++#include <linux/if_arp.h>
++#include <net/arp.h>
++
++#include <asm/arch/star_nic.h>
++
++#ifdef CONFIG_PM
++#include <linux/suspend.h>
++#endif
++
++#if 1
++#define DBG_PRINT printk
++#else
++#define DBG_PRINT(arg...)
++#endif
++
++#if 0
++#define DO_PRINT printk
++#define STAR_NIC_PRINT_ISR_STATUS
++#else
++#define DO_PRINT(arg...)
++#endif /* __DEBUG_PRINT_OUT */
++
++// VSC8601 and WavePlus Phy are the same
++#define STAR_NIC_PHY_ADDR	0
++
++#define CONFIG_STAR_NIC_NAPI
++//#define FREE_TX_SKB_MULTI		// FIXME: define this will cause samba fail
++
++#define STAR_NIC_TX_HW_CHECKSUM
++#define STAR_NIC_RX_HW_CHECKSUM
++
++#define STAR_NIC_SG
++
++#if defined(STAR_NIC_SG) && !defined(STAR_NIC_TX_HW_CHECKSUM)
++#define STAR_NIC_TX_HW_CHECKSUM
++#endif
++
++#define STAR_NIC_STATUS_ISR
++#define STAR_NIC_RXQF_ISR
++
++//#ifndef CONFIG_STAR_NIC_NAPI
++#define STAR_NIC_DELAYED_INTERRUPT
++//#endif
++
++#define MAX_PEND_INT_CNT	0x20
++#define MAX_PEND_TIME		0x20
++
++//#ifdef CONFIG_STAR_NIC_PHY_VSC8601
++//#define CONFIG_STAR_JUMBO
++//#endif
++//#define CONFIG_STAR_JUMBO
++#ifdef CONFIG_STAR_JUMBO
++#define MAX_PACKET_LEN		(2038)
++//#define MAX_PACKET_LEN		(9038)
++#else
++#define MAX_PACKET_LEN		(1536)
++#endif
++/* This constant(PKT_MIN_SIZE) can be replaced with ETH_ZLEN defined in
++ * include/linux/if_ether.h */
++#define PKT_MIN_SIZE		60
++
++//#define STAR_NIC_TIMER
++
++/* 
++ * Maximum Transmit/Receive Frame Descriptors for NIC's MAC frame
++ */
++#ifdef FREE_TX_SKB_MULTI
++#define STAR_NIC_MAX_TFD_NUM	48
++#define STAR_NIC_MAX_RFD_NUM	256
++#else
++#define STAR_NIC_MAX_TFD_NUM	48		// FIXME: original 64 will cause UDP fail
++#define STAR_NIC_MAX_RFD_NUM	64
++#endif
++
++
++#define LAN_PORT 1
++
++typedef struct
++{
++	u32		mib_rx_ok_pkt;
++	u32		mib_rx_ok_byte;
++	u32		mib_rx_runt;
++	u32		mib_rx_over_size;
++	u32		mib_rx_no_buffer_drop;
++	u32		mib_rx_crc_err;
++	u32		mib_rx_arl_drop;
++	u32		mib_rx_myvid_drop;
++	u32		mib_rx_csum_err;
++	u32		mib_rx_pause_frame;
++	u32		mib_tx_ok_pkt;
++	u32		mib_tx_ok_byte;
++	u32		mib_tx_pause_frame;
++} mib_info_t;
++
++/* store this information for the driver.. */
++struct star_nic_private {
++	struct napi_struct      napi;
++	struct net_device       *dev;
++	struct net_device_stats stats;
++	spinlock_t lock;
++	int dev_index;
++	u8 phy_addr;
++	u16 phy_id;
++	mib_info_t mib_info;
++};
++
++/*
++ * Network Driver, Receive/Send and Initial Buffer Function
++ */
++typedef struct {
++	// 1st 32Bits
++	u32 data_ptr;
++
++	// 2nd  32Bits
++	u32 length:16;
++	u32 reserved0:7;
++	u32 tco:1;
++	u32 uco:1;
++	u32 ico:1;
++	u32 insv:1;
++	u32 intr:1;
++	u32 ls:1;
++	u32 fs:1;
++	u32 eor:1;
++	u32 cown:1;
++
++	// 3rd 32Bits
++	u32 vid:12;
++	u32 cfi:1;
++	u32 pri:3;
++	u32 epid:16;
++
++	// 4th 32Bits
++	u32 reserved1;
++} __attribute__((packed)) STAR_NIC_TXDESC;
++
++typedef struct {
++	// 1st 32Bits
++	u32 data_ptr;
++
++	// 2nd  32Bits
++	u32 length:16;
++	u32 l4f:1;
++	u32 ipf:1;
++	u32 prot:2;
++	u32 vted:1;
++	u32 mymac:1;
++	u32 hhit:1;
++	u32 rmc:1;
++	u32 crce:1;
++	u32 osize:1;
++	u32 reserved0:2;
++	u32 ls:1;
++	u32 fs:1;
++	u32 eor:1;
++	u32 cown:1;
++
++	// 3rd 32Bits
++	u32 vid:12;
++	u32 cfi:1;
++	u32 pri:3;
++	u32 epid:16;
++
++	// 4th 32Bits
++	u32 reserved1;
++} __attribute__((packed)) STAR_NIC_RXDESC;
++
++/* 
++ * Transmit Frame Descriptor Ring for TFDS
++ */
++typedef struct {
++	u32			phy_addr;
++	STAR_NIC_TXDESC		*vir_addr;
++	u32			cur_index; // TX's current will point to Free Descriptors
++#if defined(FREE_TX_SKB_MULTI) || defined(STAR_NIC_TIMER)
++	u32			to_free_index;
++#endif
++	struct sk_buff		*skb_ptr[STAR_NIC_MAX_TFD_NUM]; // TX's sk_buff ptr
++} TXRING_INFO;
++
++/* 
++ * Receive Frame Descriptor Ring for RFDS
++ */
++typedef struct {
++	u32			phy_addr;
++	STAR_NIC_RXDESC		*vir_addr;
++	u32			cur_index;
++	struct sk_buff		*skb_ptr[STAR_NIC_MAX_RFD_NUM];	// RX's sk_buff ptr
++} RXRING_INFO;
++
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,32)
++#define IRQ_RETURN void
++#define IRQ_HANDLED 
++static const char star_nic_driver_version[] =
++	"Star NIC Driver(for Linux Kernel 2.4) - Star Semiconductor\n";
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++#define IRQ_RETURN irqreturn_t
++static const char star_nic_driver_version[] =
++	"Star NIC Driver(for Linux Kernel 2.6) - Star Semiconductor\n";
++#endif
++
++//========================================================
++#ifdef CONFIG_STAR_NIC_PHY_INTERNAL_PHY
++#define FE_PHY_LED_MODE (0x1 << 12)
++#define CONFIG_INTERNEL_PHY_PATCH
++#endif
++
++#ifdef CONFIG_INTERNEL_PHY_PATCH
++#define INTERNAL_PHY_PATCH_CHECKCNT	16
++#define INTERNAL_PHY_PATCH_CHECK_PERIOD	1000 //ms
++static struct timer_list internal_phy_timer;
++static void internal_phy_patch_check(int);
++static void internal_phy_update(unsigned long data);
++#endif
++//========================================================
++
++extern void fa_dma_inv_range(unsigned long s, unsigned long e);
++extern void fa_dma_clean_range(unsigned long s, unsigned long e);
++
++#define increase_cyclic(var, limit) {\
++				var++; \
++				if (var>=limit) var=0;\
++			}
++
++//static struct net_device *CUR_NAPI_DEV;
++static struct net_device *STAR_NIC_LAN_DEV;
++
++static int install_isr_account = 0;
++static int is_qf = 0; // determine queue full state
++
++static spinlock_t star_nic_send_lock;
++
++static TXRING_INFO txring;
++static RXRING_INFO rxring;
++
++static struct proc_dir_entry *star_nic_proc_entry;
++
++static u8 default_mac_addr[] = { 0x08, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e };
++
++typedef struct
++{   
++	u32 vid;	//0~4095
++	u32 control;	//ENABLE or DISABLE
++} my_vlan_entry_t;
++
++static my_vlan_entry_t my_vlan_id[4] =
++{
++	{ 2, 0},	//value for my_vid0
++	{ 2, 1},	//value for my_vid1
++	{ 1, 1},	//value for my_vid2
++	{ 1, 0}		//value for my_vid3
++};
++
++
++#ifdef CONFIG_STAR_NIC_NAPI
++static void star_nic_receive_packet(int mode, int *work_done, int work_to_do);
++#else
++static void star_nic_receive_packet(int mode);
++#endif
++
++static void star_nic_phy_powerdown(struct net_device *dev);
++static void star_nic_phy_powerup(struct net_device *dev);
++
++#ifdef STAR_NIC_TIMER
++static struct timer_list star_nic_timer;
++static void star_nic_timer_func(unsigned long data)
++{
++	int i;
++	int txsd_index;
++	int txsd_current;
++	int skb_free_count = 0;
++	STAR_NIC_TXDESC volatile *txdesc_ptr;
++	unsigned long flags;
++
++	local_irq_save(flags);
++	HAL_NIC_READ_TXSD(txsd_current);
++	txsd_index = (txsd_current - (u32)txring.phy_addr) >> 4;
++	if (txsd_index > txring.to_free_index) {
++		skb_free_count = txsd_index - txring.to_free_index;
++	} else if (txsd_index <= txring.to_free_index) {
++		skb_free_count = STAR_NIC_MAX_TFD_NUM + txsd_index - txring.to_free_index;
++	}
++	for (i = 0; i < skb_free_count; i++) {
++		txdesc_ptr = txring.vir_addr + txring.to_free_index;
++		if (txdesc_ptr->cown == 0) {
++			break;
++		}
++		if (txring.skb_ptr[txring.to_free_index]) {
++			dev_kfree_skb_any(txring.skb_ptr[txring.to_free_index]);
++			txring.skb_ptr[txring.to_free_index] = NULL;
++		}
++		txring.to_free_index++;
++		if (txring.to_free_index == STAR_NIC_MAX_TFD_NUM) {
++			txring.to_free_index = 0;
++		}
++	}
++	local_irq_restore(flags);
++}
++#endif
++
++#if 0
++#define between(x, start, end) ((x)>=(start) && (x)<=(end))
++static void print_packet(unsigned char *data, int len) 
++{
++	int i, j;
++
++	printk("packet length: %d%s:\n", len, len>100?"(only show the first 100 bytes)":"");
++	if (len > 100) {
++		len = 100;
++	}
++	for (i = 0; len;) {
++		if (len >=16) {
++			for (j=0;j<16;j++) {
++				printk("%02x ", data[i++]);
++			}
++			printk("| ");
++			i -= 16;
++			for(j=0;j<16;j++) {
++				if (between(data[i], 0x21, 0x7e) ) {
++					printk("%c", data[i++]);
++				} else {
++					printk(".");
++					i++;
++				}
++			}
++			printk("\n");
++			len -= 16;
++		} else {
++			/* last line */
++			for (j = 0; j < len; j++) {
++				printk("%02x ", data[i++]);
++			}
++			for (;j < 16; j++) {
++				printk("   ");
++			}
++			printk("| ");
++			i -= len;
++			for (j = 0;j < len; j++) {
++				if (between(data[i], 0x21, 0x7e)) {
++					printk("%c", data[i++]);
++				} else {
++					printk(".");
++					i++;
++				}
++			}
++			for (; j < 16; j++) {
++				printk(" ");
++			}
++			printk("\n");
++			len = 0;
++		}
++	}
++
++	return;
++}
++#endif /* Disable function print_packet */ 
++
++#ifdef STAR_NIC_DEBUG
++static void star_nic_show_format_reg(u32 val)
++{
++	int i;
++
++	for (i = 31; i >= 0; i--) {
++		if (val & ((unsigned long)1 << i)) {
++			printk("[%02d:1] ", i);
++		} else {
++			printk("[%02d:0] ", i);
++		}
++		if ((i % 8) == 0) {
++			printk("\n");
++		}
++	}
++	printk("==================================================================\n");
++}
++
++static void star_nic_show_reg(void)
++{
++	u32 reg_val;
++
++	printk("\n");
++
++	reg_val = NIC_MEM_MAP_VALUE(0x000);
++	printk("NIC REG OFF 0x000: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x004);
++	printk("NIC REG OFF 0x004: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x008);
++	printk("NIC REG OFF 0x008: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x00C);
++	printk("NIC REG OFF 0x00C: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x010);
++	printk("NIC REG OFF 0x010: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x014);
++	printk("NIC REG OFF 0x014: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x018);
++	printk("NIC REG OFF 0x018: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x01C);
++	printk("NIC REG OFF 0x01C: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x020);
++	printk("NIC REG OFF 0x020: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x024);
++	printk("NIC REG OFF 0x024: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x028);
++	printk("NIC REG OFF 0x028: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x030);
++	printk("NIC REG OFF 0x030: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x034);
++	printk("NIC REG OFF 0x034: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x038);
++	printk("NIC REG OFF 0x038: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x03C);
++	printk("NIC REG OFF 0x03C: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x040);
++	printk("NIC REG OFF 0x040: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x044);
++	printk("NIC REG OFF 0x044: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x048);
++	printk("NIC REG OFF 0x048: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x04C);
++	printk("NIC REG OFF 0x04C: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x050);
++	printk("NIC REG OFF 0x050: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x054);
++	printk("NIC REG OFF 0x054: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x058);
++	printk("NIC REG OFF 0x058: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x05C);
++	printk("NIC REG OFF 0x05C: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++}
++#endif
++
++static void star_nic_mib_reset(void)
++{
++	u32 v;
++	unsigned long flags;
++
++	local_irq_save(flags);
++	v = NIC_MIB_RX_OK_PKT_CNTR;
++	v = NIC_MIB_RX_OK_BYTE_CNTR;
++	v = NIC_MIB_RX_RUNT_BYTE_CNTR;
++	v = NIC_MIB_RX_OSIZE_DROP_PKT_CNTR;
++	v = NIC_MIB_RX_NO_BUF_DROP_PKT_CNTR;
++	v = NIC_MIB_RX_CRC_ERR_PKT_CNTR;
++	v = NIC_MIB_RX_ARL_DROP_PKT_CNTR;
++	v = NIC_MIB_MYVLANID_MISMATCH_DROP_PKT_CNTR;
++	v = NIC_MIB_RX_CHKSUM_ERR_PKT_CNTR;
++	v = NIC_MIB_RX_PAUSE_FRAME_PKT_CNTR;
++	v = NIC_MIB_TX_OK_PKT_CNTR;
++	v = NIC_MIB_TX_OK_BYTE_CNTR;
++	v = NIC_MIB_TX_PAUSE_FRAME_CNTR;
++	local_irq_restore(flags);
++}
++
++static void star_nic_mib_read(struct net_device *dev)
++{
++	struct star_nic_private *priv = netdev_priv(dev);
++	unsigned long flags;
++
++	local_irq_save(flags);
++	priv->mib_info.mib_rx_ok_pkt		+= NIC_MIB_RX_OK_PKT_CNTR;
++	priv->mib_info.mib_rx_ok_byte		+= NIC_MIB_RX_OK_BYTE_CNTR;
++	priv->mib_info.mib_rx_runt		+= NIC_MIB_RX_RUNT_BYTE_CNTR;
++	priv->mib_info.mib_rx_over_size		+= NIC_MIB_RX_OSIZE_DROP_PKT_CNTR;
++	priv->mib_info.mib_rx_no_buffer_drop	+= NIC_MIB_RX_NO_BUF_DROP_PKT_CNTR;
++	priv->mib_info.mib_rx_crc_err		+= NIC_MIB_RX_CRC_ERR_PKT_CNTR;
++	priv->mib_info.mib_rx_arl_drop		+= NIC_MIB_RX_ARL_DROP_PKT_CNTR;
++	priv->mib_info.mib_rx_myvid_drop	+= NIC_MIB_MYVLANID_MISMATCH_DROP_PKT_CNTR;
++	priv->mib_info.mib_rx_csum_err		+= NIC_MIB_RX_CHKSUM_ERR_PKT_CNTR;
++	priv->mib_info.mib_rx_pause_frame	+= NIC_MIB_RX_PAUSE_FRAME_PKT_CNTR;
++	priv->mib_info.mib_tx_ok_pkt		+= NIC_MIB_TX_OK_PKT_CNTR;
++	priv->mib_info.mib_tx_ok_byte		+= NIC_MIB_TX_OK_BYTE_CNTR;
++	priv->mib_info.mib_tx_pause_frame	+= NIC_MIB_TX_PAUSE_FRAME_CNTR;
++	local_irq_restore(flags);
++}
++
++static int star_nic_write_phy(u8 phy_addr, u8 phy_reg, u16 write_data)
++{
++	int i;
++
++	if (phy_addr > 31) {
++		return 0;
++	}
++
++	//clear previous rw_ok status
++	NIC_PHY_CONTROL_REG0 = (0x1 << 15);
++ 
++	NIC_PHY_CONTROL_REG0 = ((phy_addr & 0x1F) |   
++		((phy_reg & 0x1F) << 8) |
++		(0x1 << 13) |
++		((write_data & 0xFFFF) << 16));
++
++	for (i = 0; i < 10000; i++) {
++		// if write command completed
++		if ((NIC_PHY_CONTROL_REG0) & (0x1 << 15)) {
++			// clear the rw_ok status, and clear other bits value
++			NIC_PHY_CONTROL_REG0 = (0x1 << 15);
++			return (0);    /* for ok indication */
++		}
++		udelay(1000);
++	}
++
++	printk("star_nic_write_phy() failed!! phy_addr:0x%x phy_reg:0x%x write_data:0x%x\n",
++		phy_addr, phy_reg, write_data);
++	return (-1);    /* for failure indication */
++}
++
++static int star_nic_read_phy(u8 phy_addr, u8 phy_reg, u16 *read_data)
++{
++	u32 status;
++	int i;
++
++	if (phy_addr > 31) {
++		return 0;
++	}
++
++	// clear previous rw_ok status
++	NIC_PHY_CONTROL_REG0 = (0x1 << 15);
++
++	NIC_PHY_CONTROL_REG0 = ((phy_addr & 0x1F) | 
++		((phy_reg & 0x1F) << 8) | 
++		(0x1 << 14));    
++
++	for (i = 0; i < 10000; i++) {
++		status = NIC_PHY_CONTROL_REG0;
++		if (status & (0x1 << 15)) {
++			// clear the rw_ok status, and clear other bits value
++			NIC_PHY_CONTROL_REG0 = (0x1 << 15);
++			*read_data = (u16)((status >> 16) & 0xFFFF);
++			return (0);    /* for ok indication */
++		}
++		udelay(1000);
++	}
++
++	printk("star_nic_read_phy() failed!! phy_addr:0x%x phy_reg:0x%x\n",
++		phy_addr, phy_reg);
++	return (-1);    /* for failure indication */
++}
++
++static int star_nic_dma_config(struct net_device *dev)
++{
++	u32 dma_config = 0;
++
++	dma_config = NIC_DMA_CONFIG_REG;
++
++#if 1
++	/* Config TX DMA */ 
++	dma_config &=  ~(0x3 << 6); //TX auto polling :1  us
++	//dma_config |=  (0x1 << 6); //TX auto polling :10 us
++	dma_config |=  (0x2 << 6); //TX auto polling :100us
++	//dma_config |=  (0x3 << 6); //TX auto polling :1000us
++	dma_config |=  (0x1 << 5); //TX auto polling C-bit enable
++	dma_config &=  ~(0x1 << 4); //TX can transmit packets,No suspend
++#endif
++
++#if 1
++	/* Config RX DMA */
++	dma_config &=  ~(0x3 << 2); //RX auto polling :1  us
++	//dma_config |=  (0x1 << 2); //RX auto polling :10 us
++	dma_config |=  (0x2 << 2); //RX auto polling :100us
++	//dma_config |=  (0x3 << 2); //RX auto polling :1000us
++	dma_config |=  (0x1 << 1); //RX auto polling C-bit enable
++	dma_config &=  ~0x1; //RX can receive packets, No suspend
++#endif
++
++	// 4N+2(for Linux)
++	dma_config &= ~(0x1 << 16);
++	// 4N
++	//dma_config |= (0x1 << 16);
++
++	NIC_DMA_CONFIG_REG = dma_config;
++
++	return 0;
++}
++
++static int star_nic_mac_config(struct net_device *dev)
++{
++	u32 mac_config;
++
++	mac_config = NIC_MAC_CONTROL_REG;
++
++#ifdef STAR_NIC_TX_HW_CHECKSUM
++	// Tx ChkSum offload On: TCP/UDP/IP
++	mac_config |= (0x1 << 26);
++#else
++	// Tx ChkSum offload Off: TCP/UDP/IP
++	mac_config &= ~(0x1 << 26);
++#endif
++
++#ifdef STAR_NIC_RX_HW_CHECKSUM
++	// Rx ChkSum offload On: TCP/UDP/IP
++	mac_config |= (0x1 << 25);
++#else
++	// Rx ChkSum offload Off: TCP/UDP/IP
++	mac_config &= ~(0x1 << 25);
++#endif
++
++	mac_config |= (0x1 << 24);	// Accept CSUM error pkt
++	//mac_config &= ~(0x1 << 24);	// Discard CSUM error pkt
++
++	//mac_config |= (0x1 << 23);	// IST Enable
++	mac_config &= ~(0x1 << 23);	// IST disable
++
++	mac_config |= (0x1 << 22);	// Strip vlan tag
++	//mac_config &= ~(0x1 << 22);	// Keep vlan tag
++
++	mac_config |= (0x1 << 21);	// Accept CRC error pkt
++	//mac_config &= ~(0x1 << 21);	// Disacrd CRC error pkt
++
++	mac_config |= (0x1 << 20);	// CRC strip
++	//mac_config &= ~(0x1 << 20);	// Keep CRC
++
++#ifdef CONFIG_STAR_JUMBO
++	mac_config |= (0x1 << 18);	// Accept oversize pkt
++#else
++	mac_config &= ~(0x1 << 18);	// Discard oversize pkt
++#endif
++
++	mac_config &= ~(0x3 << 16);	// clear, set 1518
++
++#ifdef CONFIG_STAR_JUMBO
++	mac_config |= (0x3 << 16);	//set reserved, for jumbo frame
++#else
++	mac_config |= (0x2 << 16);	// 1536
++	//mac_config |= (0x1 << 16);	// 1522
++#endif
++
++	// IPG
++	mac_config |= (0x1f << 10);
++
++	// Do not skip 16 consecutive collisions pkt
++	mac_config |= (0x1 << 9);	// allow to re-tx
++	//mac_config &= ~(0x1 << 9);	// drop pkt
++
++	mac_config |= (0x1 << 8);	// Fast retry
++	//mac_config &= ~(0x1 << 8);	// standard
++
++	NIC_MAC_CONTROL_REG = mac_config;
++
++	return 0;
++}
++
++static int star_nic_fc_config(struct net_device *dev)
++{
++	u32 fc_config;
++
++	fc_config = NIC_FLOW_CONTROL_CONFIG_REG;
++
++	// Send pause on frame threshold
++	fc_config &= ~(0xfff << 16);	// Clear
++	fc_config |= (0x360 << 16);	// Set
++
++	//fc_config |= (0x1 << 8);	// Enable UC_PAUSE
++	fc_config &= ~(0x1 << 8);	// Disable UC_PAUSE
++
++	fc_config |= (0x1 << 7);	// Enable Half Duplex backpressure
++	//fc_config &= ~(0x1 << 7);	// Disable Half Duplex backpressure
++
++    	//fc_config |= (0x1 << 6);	// CRS-based BP
++	fc_config &= ~(0x1 << 6);	// Collision-based BP
++
++	//fc_config |= (0x1 << 5);	// Enable max BP collision
++	fc_config &= ~(0x1 << 5);	// Disable max BP collision
++
++	// max BP collision count
++	fc_config &= ~(0x1f);		// Clear
++	fc_config |= (0xc);		// Set
++
++	NIC_FLOW_CONTROL_CONFIG_REG = fc_config;
++
++	return 0;
++}
++
++static int star_nic_phy_config(struct net_device *dev)
++{
++	struct star_nic_private *priv = netdev_priv(dev);
++	u32 phy_config = NIC_PHY_CONTROL_REG1;
++#ifdef CONFIG_STAR_NIC_PHY_VSC8601
++	u32 phy_addr=0;
++#endif /* CONFIG_STAR_NIC_PHY_VSC8601 */
++	//int i;
++
++#ifdef CONFIG_STAR_NIC_PHY_INTERNAL_PHY 
++	printk("Star Internal PHY\n");
++
++#if 0
++	{
++		u16 phy_data;
++		// restart the internal phy
++		star_nic_write_phy(STAR_NIC_PHY_ADDR, 0, 0x8000);
++		while (1) {
++			star_nic_read_phy(STAR_NIC_PHY_ADDR, 0, &phy_data);
++			if ( (phy_data&0x8000) ==0x0000) { // phy now at normal mode
++				break;
++			}
++		}
++	}
++#endif
++
++	priv->phy_addr = STAR_NIC_PHY_ADDR;
++	// set phy addr for auto-polling
++	phy_config |= (priv->phy_addr & 0x1f) << 24;
++
++	// set internal phy mode
++	// internel 10/100 phy
++	phy_config |= 0x1 << 18;
++
++	// MII
++	phy_config &= ~(0x1 << 17);
++
++	// MAC mode
++	phy_config &= ~(0x1 << 16);
++
++	// config PHY LED bit[13:12]
++	star_nic_read_phy(priv->phy_addr, 31, (u16 *)(&phy_config));
++	phy_config &= ~(0x3 << 12); // clear LED control
++	phy_config |= FE_PHY_LED_MODE;
++	star_nic_write_phy(priv->phy_addr, 31, phy_config);
++#endif
++#ifdef CONFIG_STAR_NIC_PHY_VSC8601
++	u16 phy_data;
++
++	printk("VSC8601 Chip\n");
++
++	// phy addr for auto-polling
++	phy_config |= ((phy_addr & 0x1f) << 24);
++
++	// set external phy mode
++	phy_config &= ~(0x1 << 18);
++
++	// set RGMII
++	phy_config |= (0x1 << 17);
++
++	// set MII interface
++	phy_config &= ~(0x1 << 16);
++
++	NIC_PHY_CONTROL_REG1 = phy_config;
++//=========================================================
++
++	priv->phy_addr = STAR_NIC_PHY_ADDR;
++	// set phy addr for auto-polling
++	phy_config |= (priv->phy_addr & 0x1f) << 24;
++
++	// set external phy mode
++	// MII/RGMII interface
++	phy_config &= ~(0x1 << 18);
++
++	// RGMII
++	phy_config |= (0x1 << 17);
++
++	// MAC mode
++	phy_config &= ~(0x1 << 16);
++
++	star_nic_read_phy(priv->phy_addr, 3, &phy_data);
++	if ((phy_data & 0x000f) == 0x0000) { // type A chip
++		u16 tmp16;
++
++		printk("VSC8601 Type A Chip\n");
++		star_nic_write_phy(priv->phy_addr, 31, 0x52B5);
++		star_nic_write_phy(priv->phy_addr, 16, 0xAF8A);
++
++		phy_data = 0x0;
++		star_nic_read_phy(priv->phy_addr, 18, &tmp16);
++		phy_data |= (tmp16 & ~0x0);
++		star_nic_write_phy(priv->phy_addr, 18, phy_data);
++
++		phy_data = 0x0008;
++		star_nic_read_phy(priv->phy_addr, 17, &tmp16);
++		phy_data |= (tmp16 & ~0x000C);
++		star_nic_write_phy(priv->phy_addr, 17, phy_data);        	
++
++		star_nic_write_phy(priv->phy_addr, 16, 0x8F8A);        	
++
++		star_nic_write_phy(priv->phy_addr, 16, 0xAF86);        	
++
++		phy_data = 0x0008;
++		star_nic_read_phy(priv->phy_addr, 18, &tmp16);
++		phy_data |= (tmp16 & ~0x000C);
++		star_nic_write_phy(priv->phy_addr, 18, phy_data);        	
++
++		phy_data = 0x0;
++		star_nic_read_phy(priv->phy_addr, 17, &tmp16);
++		phy_data |= (tmp16 & ~0x0);
++		star_nic_write_phy(priv->phy_addr, 17, phy_data);        	
++
++		star_nic_write_phy(priv->phy_addr, 16, 0x8F8A);        	
++
++		star_nic_write_phy(priv->phy_addr, 16, 0xAF82);        	
++
++		phy_data = 0x0;
++		star_nic_read_phy(priv->phy_addr, 18, &tmp16);
++		phy_data |= (tmp16 & ~0x0);
++		star_nic_write_phy(priv->phy_addr, 18, phy_data);        	
++
++		phy_data = 0x0100;
++		star_nic_read_phy(priv->phy_addr, 17, &tmp16);
++		phy_data |= (tmp16 & ~0x0180);
++		star_nic_write_phy(priv->phy_addr, 17, phy_data);        	
++
++		star_nic_write_phy(priv->phy_addr, 16, 0x8F82);        	
++
++		star_nic_write_phy(priv->phy_addr, 31, 0x0);        	
++           
++		//Set port type: single port
++		star_nic_read_phy(priv->phy_addr, 9, &phy_data);        	
++		phy_data &= ~(0x1 << 10);
++		star_nic_write_phy(priv->phy_addr, 9, phy_data);        	
++	} else if ((phy_data & 0x000f) == 0x0001) { // type B chip
++		printk("VSC8601 Type B Chip\n");
++		star_nic_read_phy(priv->phy_addr, 23, &phy_data);
++		phy_data |= ( 0x1 << 8); //set RGMII timing skew
++		star_nic_write_phy(priv->phy_addr, 23, phy_data);
++	}
++
++	// change to extened registers
++	star_nic_write_phy(priv->phy_addr, 31, 0x0001);
++
++	star_nic_read_phy(priv->phy_addr, 28, &phy_data);
++	phy_data &= ~(0x3 << 14); // set RGMII TX timing skew
++	phy_data |= (0x3 << 14); // 2.0ns
++	phy_data &= ~(0x3 << 12); // set RGMII RX timing skew
++	phy_data |= (0x3 << 12); // 2.0ns
++	star_nic_write_phy(priv->phy_addr, 28, phy_data);
++
++	// change to normal registers
++	star_nic_write_phy(priv->phy_addr, 31, 0x0000);
++
++	// set TX and RX clock skew
++	//NIC_TEST_0_REG = (0x2 << 2) | (0x2 << 0);
++
++#endif
++
++#ifdef CONFIG_STAR_NIC_PHY_IP101A
++	// ICPlus IP101A
++	printk("ICPlus IP101A\n");
++	priv->phy_addr = 1;
++	// set phy addr for auto-polling
++	phy_config |= (priv->phy_addr & 0x1f) << 24;
++
++	// set external phy mode
++	// MII/RGMII interface
++	phy_config &= ~(0x1 << 18);
++
++	// MII
++	phy_config &= ~(0x1 << 17);
++
++	// MAC mode
++	phy_config &= ~(0x1 << 16);
++#endif
++
++/* robin 080102 				*/
++/* added ICPlus IP1001 support	*/
++#ifdef CONFIG_STAR_NIC_PHY_IP1001
++u16 phy_data;
++
++u32 phy_addr = 1;
++
++phy_config = NIC_PHY_CONTROL_REG1;
++
++	// set phy addr for auto-polling
++	phy_config |= ((phy_addr & 0x1f) << 24);
++
++	// set external phy mode
++	// MII/RGMII interface
++	phy_config &= ~(0x1 << 18);
++
++	// RGMII
++	phy_config |= (0x1 << 17);
++
++	// MAC mode
++	phy_config &= ~(0x1 << 16);
++
++ NIC_PHY_CONTROL_REG1 = phy_config;
++    star_nic_read_phy(phy_addr,2,&phy_data);
++    //printf("\n phy.reg2=0x%04x",phy_data);
++	
++#if 1//set AN capability
++
++
++    star_nic_read_phy(phy_addr,4,&phy_data);
++
++    phy_data &= ~(0xf<<5);//clear
++    phy_data |= (0x1<<5); //10Half
++    phy_data |= (0x1<<6); //10Full
++    phy_data |= (0x1<<7); //100Half
++    phy_data |= (0x1<<8); //100Full
++//    phy_data &= ~(0x1<<10); //FC off
++    phy_data |= (0x1<<10); //FC on
++    star_nic_write_phy(phy_addr,4,phy_data);
++
++
++    star_nic_read_phy(phy_addr,9,&phy_data);
++
++    phy_data |= (0x1<<9); //1000Full on
++
++    phy_data &= ~(0x1<<10); 
++
++    phy_data |= (0x1<<12); 
++
++    star_nic_write_phy(phy_addr,9,phy_data);
++
++
++
++
++    star_nic_read_phy(phy_addr,16,&phy_data);
++
++    phy_data &= ~(0x1<<11); //Smart function off
++
++    phy_data |=  (0x1<<0); //TX delay
++
++    phy_data |=  (0x1<<1); //RX delay
++
++    star_nic_write_phy(phy_addr,16,phy_data);
++
++    star_nic_read_phy(phy_addr,16,&phy_data);
++    //printf("\n phy.reg16=0x%04x",phy_data);
++
++
++//    Hal_Nic_Read_PHY(NIC_PHY_ADDRESS,20,&phy_data);
++//
++//    phy_data &= ~(0x1<<2); 
++//
++//    phy_data |=  (0x1<<9); 
++//    Hal_Nic_Write_PHY(NIC_PHY_ADDRESS,20,phy_data);
++
++
++
++
++    star_nic_read_phy(phy_addr,0,&phy_data);
++    phy_data |= (0x1<<9); //re-AN
++    star_nic_write_phy(phy_addr,0,phy_data);
++
++
++    star_nic_read_phy(phy_addr,9,&phy_data);
++    //printf("\n phy.reg9=0x%04x",phy_data);
++
++  
++#endif	
++#endif // CONFIG_STAR_NIC_PHY_IP1001
++/* robin 080102 - end of modification */
++
++
++
++	phy_config |= (0x1 << 8); // AN On
++	//phy_config &= ~(0x1 << 8); // AN off
++
++	if (!((phy_config >> 8) & 0x1)) { // AN disbale
++		// Force to FullDuplex mode
++		phy_config &= ~(0x1 << 11); // Half
++
++		// Force to 100Mbps mode
++		phy_config &= ~(0x3 << 9); // clear to 10M
++		phy_config |= (0x1 << 9); // set to 100M
++	}
++
++	// Force TX FlowCtrl On,in 1000M
++	phy_config |= (0x1 << 13);
++
++	// Force TX FlowCtrl On, in 10/100M
++	phy_config |= (0x1 << 12);
++
++	// Enable MII auto polling
++	phy_config &= ~(0x1 << 7); // auto-polling enable
++	//phy_config |= (0x1 << 7); // auto-polling disable
++
++	NIC_PHY_CONTROL_REG1 = phy_config;
++#if 1
++	star_nic_phy_powerdown(dev);
++#endif
++
++	return 0;
++}
++
++static int star_nic_vlan_config(struct net_device *dev)
++{
++	u32 vlan_id;
++
++	//1.Setup MyVLAN ID0_1
++	vlan_id  = 0; //clear
++	vlan_id |= (my_vlan_id[0].vid & 0x0fff);
++	vlan_id |= ((my_vlan_id[1].vid & 0x0fff) << 16);
++	NIC_MY_VLANID_0_1 = vlan_id;
++
++	//2.Setup MyVLAN ID2_3
++	vlan_id  = 0; //clear
++	vlan_id |= (my_vlan_id[2].vid & 0x0fff);
++	vlan_id |= ((my_vlan_id[3].vid & 0x0fff) << 16);
++	NIC_MY_VLANID_2_3 = vlan_id;
++
++	//3.Setup vlan_id control bits
++	NIC_MY_VLANID_CONTROL_REG = ( (my_vlan_id[0].control << 0) |
++		(my_vlan_id[1].control << 1) |
++		(my_vlan_id[2].control << 2) |
++		(my_vlan_id[3].control << 3) );
++
++	return 0;
++}
++
++static int star_nic_arl_config(struct net_device *dev)
++{
++	u32 arl_config;
++
++	arl_config = NIC_ARL_CONFIG_REG;
++	arl_config |= (0x1 << 4); // Misc Mode ON
++	//arl_config &= ~(0x1 << 4); // Misc Mode Off
++	arl_config |= (0x1 << 3); // My MAC only enable
++	arl_config &= ~(0x1 << 2); // Learn SA On
++	arl_config &= ~(0x1 << 1); // Forward MC to CPU
++	arl_config &= ~(0x1); // Hash direct mode
++	NIC_ARL_CONFIG_REG = arl_config;
++
++	return 0;
++}
++
++#if 0
++static void star_nic_interrupt_disable(void)
++{
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_STATUS_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_TXTC_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXRC_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_TXQE_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXQF_BIT_INDEX);
++}
++#endif /* Disable function star_nic_interrupt_disable */
++
++static void star_nic_interrupt_enable(void)
++{
++#ifdef STAR_NIC_STATUS_ISR
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_STATUS_BIT_INDEX);
++#endif
++	
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_RXRC_BIT_INDEX);
++
++#ifdef STAR_NIC_RXQF_ISR
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_RXQF_BIT_INDEX);
++#endif
++}
++
++#if 0
++static int star_nic_show_rxdesc(char *page)
++{
++	int i;
++	int num = 0;
++	u32 rxsd_current;
++	int rxsd_index;
++	STAR_NIC_RXDESC volatile *rxdesc_ptr = rxring.vir_addr;
++
++	HAL_NIC_READ_RXSD(rxsd_current);
++	rxsd_index = (rxsd_current - (u32)rxring.phy_addr) >> 4;
++
++	num += sprintf(page + num, "rxring.cur_index: %d\n", rxring.cur_index);
++	num += sprintf(page + num, "rxsd_index:       %d\n", rxsd_index);
++
++	for (i = 0; i < STAR_NIC_MAX_RFD_NUM; i++) {
++		num += sprintf(page + num, "rxring[%02d].cown ==> %d\n", i, rxdesc_ptr->cown);
++		rxdesc_ptr++;
++	}
++
++	return num;
++}
++#endif /* Disable function star_nic_show_rxdesc */
++
++#if 0
++static int star_nic_show_txdesc(char *page)
++{
++	int i;
++	int num = 0;
++	u32 txsd_current;
++	int txsd_index;
++	STAR_NIC_TXDESC volatile *txdesc_ptr = txring.vir_addr;
++
++	HAL_NIC_READ_TXSD(txsd_current);
++	txsd_index = (txsd_current - (u32)txring.phy_addr) >> 4;
++
++	num += sprintf(page + num, "txring.cur_index: %d\n", txring.cur_index);
++	num += sprintf(page + num, "txsd_index:       %d\n", txsd_index);
++
++	for (i = 0; i < STAR_NIC_MAX_TFD_NUM; i++) {
++		num += sprintf(page + num, "txring[%02d].cown ==> %d\n", i, txdesc_ptr->cown);
++		txdesc_ptr++;
++	}
++
++	return num;
++}
++#endif /* star_nic_show_txdesc */
++
++static int star_nic_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
++{
++	struct star_nic_private *priv = netdev_priv(STAR_NIC_LAN_DEV);
++	int num = 0;
++
++	star_nic_mib_read(STAR_NIC_LAN_DEV);
++	num += sprintf(page + num, "mib_rx_ok_pkt          %08d\n", priv->mib_info.mib_rx_ok_pkt);
++	num += sprintf(page + num, "mib_rx_ok_byte         %08d\n", priv->mib_info.mib_rx_ok_byte);
++	num += sprintf(page + num, "mib_rx_runt            %08d\n", priv->mib_info.mib_rx_runt);
++	num += sprintf(page + num, "mib_rx_over_size       %08d\n", priv->mib_info.mib_rx_over_size);
++	num += sprintf(page + num, "mib_rx_no_buffer_drop  %08d\n", priv->mib_info.mib_rx_no_buffer_drop);
++	num += sprintf(page + num, "mib_rx_crc_err         %08d\n", priv->mib_info.mib_rx_crc_err);
++	num += sprintf(page + num, "mib_rx_arl_drop        %08d\n", priv->mib_info.mib_rx_arl_drop);
++	num += sprintf(page + num, "mib_rx_myvid_drop      %08d\n", priv->mib_info.mib_rx_myvid_drop);
++	num += sprintf(page + num, "mib_rx_csum_err        %08d\n", priv->mib_info.mib_rx_csum_err);
++	num += sprintf(page + num, "mib_rx_pause_frame     %08d\n", priv->mib_info.mib_rx_pause_frame);
++	num += sprintf(page + num, "mib_tx_ok_pkt          %08d\n", priv->mib_info.mib_tx_ok_pkt);
++	num += sprintf(page + num, "mib_tx_ok_byte         %08d\n", priv->mib_info.mib_tx_ok_byte);
++	num += sprintf(page + num, "mib_tx_pause_frame     %08d\n", priv->mib_info.mib_tx_pause_frame);
++
++	//num += star_nic_show_rxdesc(page + num);
++	//num += star_nic_show_txdesc(page + num);
++
++	return num;
++}
++
++
++static int
++star_nic_write_proc(struct file *file, const char __user *buffer,
++	unsigned long count, void *data)
++{
++	char *str;
++	char *cmd;
++
++	if (count > 0) {
++		str = (char *)buffer,
++		cmd = strsep(&str, "\t \n");
++		if (!cmd) goto err_out;
++		if (strcmp(cmd, "clear") == 0) {
++			struct star_nic_private *priv = netdev_priv(STAR_NIC_LAN_DEV);
++
++			star_nic_mib_read(STAR_NIC_LAN_DEV);
++			memset(&priv->mib_info,0,sizeof(priv->mib_info));
++
++		//} else if (strcmp(cmd, "write") == 0) {
++		} else {
++			goto err_out;
++		}
++	}
++
++	return count;
++
++err_out:
++	return -EFAULT;
++}
++
++static void star_nic_phy_powerdown(struct net_device *dev)
++{
++	struct star_nic_private *priv = netdev_priv(dev);
++	u16 phy_data = 0;
++	// power down the PHY
++	star_nic_read_phy(priv->phy_addr, 0, &phy_data);
++	phy_data |= (0x1 << 11);
++	star_nic_write_phy(priv->phy_addr, 0, phy_data);
++
++	// set hight
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
++	// set low
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1 << 15);
++}
++
++static void star_nic_phy_powerup(struct net_device *dev)
++{
++	struct star_nic_private *priv = netdev_priv(dev);
++	u16 phy_data = 0;
++	// power up the PHY
++	star_nic_read_phy(priv->phy_addr, 0, &phy_data);
++	phy_data &= ~(0x1 << 11);
++	star_nic_write_phy(priv->phy_addr, 0, phy_data);
++
++	// set hight
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
++}
++
++static void star_nic_enable(struct net_device *dev)
++{
++#if 0
++	// enable NIC clock
++	HAL_PWRMGT_ENABLE_NIC_CLOCK();
++	NIC_MAC_CONTROL_REG &= ~((u32)0x3 << 30);
++	udelay(100);
++#endif
++
++	star_nic_interrupt_enable();
++	HAL_NIC_RX_DMA_START();
++#if 1
++	star_nic_phy_powerup(dev);
++#endif
++#ifdef CONFIG_INTERNEL_PHY_PATCH
++	printk("%s: starting patch check.\n", __FUNCTION__);
++	internal_phy_patch_check(1);
++	mod_timer(&internal_phy_timer, jiffies + INTERNAL_PHY_PATCH_CHECK_PERIOD / 10);
++#endif
++
++}
++
++static void star_nic_shutdown(struct net_device *dev)
++{
++	if (install_isr_account == 0) {
++		DBG_PRINT("disable port 0\n");
++		HAL_NIC_RX_DMA_STOP();
++		HAL_NIC_TX_DMA_STOP();
++#if 0
++		NIC_MAC_CONTROL_REG |= ((u32)0x1 << 31);
++		while (!(NIC_MAC_CONTROL_REG & (0x1 << 29))) {
++			udelay(1000);
++		}
++		HAL_PWRMGT_DISABLE_NIC_CLOCK();
++		NIC_MAC_CONTROL_REG |= (0x1 <<29);
++#endif
++#ifdef CONFIG_INTERNEL_PHY_PATCH
++	printk("%s: stoping patch check.\n", __FUNCTION__);
++	del_timer_sync(&internal_phy_timer);
++#endif
++	}
++}
++
++IRQ_RETURN star_nic_receive_isr(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct star_nic_private *priv = netdev_priv(STAR_NIC_LAN_DEV);
++#ifdef CONFIG_STAR_NIC_NAPI
++	if (!test_bit(5, &STAR_NIC_LAN_DEV->state)) 
++	  napi_schedule(&priv->napi);
++#else
++#ifndef CONFIG_VIC_INTERRUPT
++	// TODO: mask interrupt
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_NIC_RXRC_BIT_INDEX);
++#endif
++	// MASK Interrupt
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXRC_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXQF_BIT_INDEX);
++
++	star_nic_receive_packet(0); // Receive Once
++
++	// TODO: unmask interrupt
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_RXRC_BIT_INDEX);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_RXQF_BIT_INDEX);
++#endif
++
++	return IRQ_HANDLED;
++}
++
++#ifdef STAR_NIC_RXQF_ISR
++IRQ_RETURN star_nic_rxqf_isr(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct star_nic_private *priv = netdev_priv(STAR_NIC_LAN_DEV);
++#ifndef CONFIG_VIC_INTERRUPT
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_NIC_RXQF_BIT_INDEX);
++#endif
++#ifdef CONFIG_STAR_NIC_NAPI
++	// because in normal state, fsql only invoke once and set_bit is atomic function.
++	// so I don't mask it.
++	set_bit(0, (unsigned long *)&is_qf);
++	if (!test_bit(5, &STAR_NIC_LAN_DEV->state)) 
++	  napi_schedule(&priv->napi);
++#else
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXRC_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXQF_BIT_INDEX);
++	
++	star_nic_receive_packet(1); // Receive at Queue Full Mode
++
++	// TODO: unmask interrupt
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_RXRC_BIT_INDEX);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_RXQF_BIT_INDEX);
++#endif
++
++	return IRQ_HANDLED;
++}
++#endif
++
++#ifdef CONFIG_PM
++int inline str8100_nic_resume();
++int inline str8100_nic_suspend(suspend_state_t state);
++#endif
++
++#ifdef STAR_NIC_STATUS_ISR
++
++IRQ_RETURN star_nic_status_isr(int irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 int_status;
++#ifdef CONFIG_PM
++	extern int nic_suspended;
++	u32 nic_suspended_tmp=nic_suspended;
++#endif
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_STATUS_BIT_INDEX);
++	HAL_NIC_READ_INTERRUPT_STATUS(int_status);
++
++	//printk("%s: NIC status:%08X \n",__FUNCTION__, int_status);
++
++	if (int_status & 0x8) {
++		star_nic_mib_read((struct net_device *)STAR_NIC_LAN_DEV);
++	}
++
++#ifdef CONFIG_PM
++	if ((int_status & 0x10)&&nic_suspended_tmp) {
++//		printk("W\n");
++		str8100_nic_resume();
++	}
++#endif
++	HAL_NIC_CLEAR_INTERRUPT_STATUS_SOURCES(int_status);
++#ifdef CONFIG_PM
++	if ((int_status & 0x10)&&nic_suspended_tmp) {
++		str8100_nic_suspend(0);
++	}
++#endif
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_STATUS_BIT_INDEX);
++
++	return IRQ_HANDLED;
++}
++#endif // STAR_NIC_STATUS_ISR
++
++static int star_nic_uninstall_isr(struct net_device *dev)
++{
++	--install_isr_account;
++
++	if (install_isr_account == 0) {
++		printk("star nic uninstall isr\n");
++		free_irq(INTC_NIC_RXRC_BIT_INDEX, STAR_NIC_LAN_DEV);
++
++#ifdef STAR_NIC_RXQF_ISR
++		free_irq(INTC_NIC_RXQF_BIT_INDEX, STAR_NIC_LAN_DEV);
++#endif
++
++#ifdef STAR_NIC_STATUS_ISR
++		free_irq(INTC_NIC_STATUS_BIT_INDEX, STAR_NIC_LAN_DEV);
++#endif
++	}
++
++	return 0;
++}
++
++static int star_nic_install_isr(struct net_device *dev)
++{
++	int retval;
++
++	if (install_isr_account == 0) {
++#ifdef STAR_NIC_DELAYED_INTERRUPT
++		NIC_DELAYED_INT_CONFIG_REG = (1 << 16) | ((MAX_PEND_INT_CNT & 0xFF) << 8) | (MAX_PEND_TIME & 0xFF);
++#endif
++		retval = request_irq(INTC_NIC_RXRC_BIT_INDEX, &star_nic_receive_isr, IRQF_SHARED, "NIC RXRC INT", STAR_NIC_LAN_DEV);
++
++		if (retval) {
++			DO_PRINT("%s: unable to get IRQ %d (irqval=%d).\n", "NIC RXRC INT", INTC_NIC_RXRC_BIT_INDEX, retval);
++			return 1;
++		}
++
++#ifdef STAR_NIC_RXQF_ISR
++		/*  QUEUE full interrupt handler */
++		retval = request_irq(INTC_NIC_RXQF_BIT_INDEX, &star_nic_rxqf_isr, IRQF_SHARED, "NIC RXQF INT", STAR_NIC_LAN_DEV);
++
++		if (retval) {
++			DO_PRINT("%s: unable to get IRQ %d (irqval=%d).\n", "NIC RXQF INT", INTC_NIC_RXQF_BIT_INDEX, retval);
++			return 2;
++		}
++#endif	
++
++#ifdef STAR_NIC_STATUS_ISR
++		/*  NIC Status interrupt handler */
++		retval = request_irq(INTC_NIC_STATUS_BIT_INDEX, &star_nic_status_isr, IRQF_SHARED, "NIC STATUS", STAR_NIC_LAN_DEV);
++
++		if (retval) {
++			DO_PRINT("%s: unable to get IRQ %d (irqval=%d).\n", "NIC STATUS INT", INTC_NIC_STATUS_BIT_INDEX, retval);
++			return 3;
++		}
++		//HAL_NIC_ENABLE_ALL_INTERRUPT_STATUS_SOURCES();
++		HAL_NIC_DISABLE_ALL_INTERRUPT_STATUS_SOURCES();
++		//Enable NIC Status Interrupt: MIB counter th (3)
++		HAL_NIC_ENABLE_INTERRUPT_STATUS_SOURCE_BIT(3);
++
++#endif
++	} // end if(install_isr_account == 0)
++
++	++install_isr_account;
++
++	return 0;
++}
++
++static int star_nic_lan_open(struct net_device *dev)
++{
++	DBG_PRINT("%s:star_nic_lan_open\n", dev->name);
++
++#ifdef MODULE
++	MOD_INC_USE_COUNT;
++#endif
++
++	//CUR_NAPI_DEV = dev;
++	//
++	struct star_nic_private *priv = netdev_priv(dev);
++	napi_enable(&priv->napi);
++
++	netif_start_queue(dev);
++
++	star_nic_install_isr(dev);
++
++	star_nic_enable(dev);
++
++	return 0;
++}
++
++static struct net_device_stats *star_nic_get_stats(struct net_device *dev)
++{
++	struct star_nic_private *priv = netdev_priv(dev);
++
++	return &priv->stats;
++}
++
++static void star_nic_timeout(struct net_device *dev)
++{
++	DBG_PRINT("%s:star_nic_timeout\n", dev->name);
++	netif_wake_queue(dev);
++	dev->trans_start = jiffies;
++}
++
++static int star_nic_close(struct net_device *dev)
++{
++#if 1
++	star_nic_phy_powerdown(dev);
++#endif
++	star_nic_uninstall_isr(dev);
++
++/* plany add 20080904 */
++#ifdef CONFIG_STAR_NIC_NAPI
++	struct star_nic_private *priv = netdev_priv(dev);
++	napi_disable(&priv->napi);
++#endif
++	netif_stop_queue(dev);
++	star_nic_shutdown(dev);
++
++#ifdef MODULE
++	MOD_DEC_USE_COUNT;
++#endif
++
++	//CUR_NAPI_DEV = STAR_NIC_LAN_DEV;
++
++	return 0;
++}
++
++static inline struct sk_buff *star_nic_alloc_skb(void)
++{
++	struct sk_buff *skb;
++
++	skb = dev_alloc_skb(MAX_PACKET_LEN + 2);
++
++	if (unlikely(!skb)) {
++		printk("\n dev_alloc_skb fail!! while allocate RFD ring !!\n");
++		return NULL;
++	}
++
++	/* Make buffer alignment 2 beyond a 16 byte boundary
++	 * this will result in a 16 byte aligned IP header after
++	 * the 14 byte MAC header is removed
++	 */
++	skb_reserve(skb, 2);	/* 16 bit alignment */
++
++	return skb;
++}
++
++static void __init star_nic_buffer_free(void)
++{
++	int i;
++
++	if (rxring.vir_addr) {
++		for (i = 0; i < STAR_NIC_MAX_RFD_NUM; i++) {
++			if (rxring.skb_ptr[i]) {
++				dev_kfree_skb(rxring.skb_ptr[i]);
++			}
++		}
++		dma_free_coherent(NULL, STAR_NIC_MAX_RFD_NUM * sizeof(STAR_NIC_RXDESC), rxring.vir_addr, rxring.phy_addr);
++		memset((void *)&rxring, 0, STAR_NIC_MAX_RFD_NUM * sizeof(STAR_NIC_RXDESC));
++	}
++
++	if (txring.vir_addr) {
++		dma_free_coherent(NULL, STAR_NIC_MAX_TFD_NUM * sizeof(STAR_NIC_TXDESC), txring.vir_addr, txring.phy_addr);
++		memset((void *)&txring, 0, STAR_NIC_MAX_TFD_NUM * sizeof(STAR_NIC_TXDESC));
++	}
++}
++
++static int __init star_nic_buffer_alloc(void)
++{
++	STAR_NIC_RXDESC	volatile *rxdesc_ptr;
++	STAR_NIC_TXDESC	volatile *txdesc_ptr;
++	struct sk_buff	*skb_ptr;
++	int err;
++	int i;
++
++	rxring.vir_addr = dma_alloc_coherent(NULL, STAR_NIC_MAX_RFD_NUM * sizeof(STAR_NIC_RXDESC), &rxring.phy_addr, GFP_KERNEL);
++	if (!rxring.vir_addr) {
++		printk("\n ERROR: Allocate RFD Failed\n");
++		err = -ENOMEM;
++		goto err_out;
++	}
++
++	txring.vir_addr = dma_alloc_coherent(NULL, STAR_NIC_MAX_TFD_NUM * sizeof(STAR_NIC_TXDESC), &txring.phy_addr, GFP_KERNEL);
++	if (!txring.vir_addr) {
++		printk("\n ERROR: Allocate TFD Failed\n");
++		err = -ENOMEM;
++		goto err_out;
++	}
++
++	// Clean RX Memory
++	memset((void *)rxring.vir_addr, 0, STAR_NIC_MAX_RFD_NUM * sizeof(STAR_NIC_RXDESC));
++	DBG_PRINT("    rxring.vir_addr=0x%08X rxring.phy_addr=0x%08X\n", (u32)rxring.vir_addr, (u32)rxring.phy_addr);
++	rxring.cur_index = 0;	// Set cur_index Point to Zero
++	rxdesc_ptr = rxring.vir_addr;
++	for (i = 0; i < STAR_NIC_MAX_RFD_NUM; i++, rxdesc_ptr++) {
++		if (i == (STAR_NIC_MAX_RFD_NUM - 1)) { 
++			rxdesc_ptr->eor = 1;	// End bit == 0;
++		}
++		skb_ptr = star_nic_alloc_skb();
++		if (!skb_ptr) {
++			printk("ERROR: Allocate skb Failed!\n");
++			err = -ENOMEM;
++			goto err_out;
++		}
++		// Trans Packet from Virtual Memory to Physical Memory
++		rxring.skb_ptr[i]	= skb_ptr;
++		rxdesc_ptr->data_ptr	= (u32)virt_to_phys(skb_ptr->data);
++		rxdesc_ptr->length	= MAX_PACKET_LEN;
++	}
++
++	// Clean TX Memory
++	memset((void *)txring.vir_addr, 0, STAR_NIC_MAX_TFD_NUM * sizeof(STAR_NIC_TXDESC));
++	DBG_PRINT("    txring.vir_addr=0x%08X txring.phy_addr=0x%08X\n", (u32)txring.vir_addr, (u32)txring.phy_addr);
++	txring.cur_index = 0;	// Set cur_index Point to Zero
++	txdesc_ptr = txring.vir_addr;
++	for (i = 0; i < STAR_NIC_MAX_TFD_NUM; i++, txdesc_ptr++) {
++		if (i == (STAR_NIC_MAX_TFD_NUM - 1)) { 
++			txdesc_ptr->eor = 1;	// End of Ring ==1
++		}
++		txdesc_ptr->cown = 1;	// TX Ring , Cown == 1
++
++#ifdef STAR_NIC_TX_HW_CHECKSUM
++		// Enable Checksum
++		txdesc_ptr->ico		= 1;
++		txdesc_ptr->uco		= 1;
++		txdesc_ptr->tco		= 1;
++#else
++		txdesc_ptr->ico		= 0;
++		txdesc_ptr->uco		= 0;
++		txdesc_ptr->tco		= 0;
++#endif
++		txring.skb_ptr[i] 	= NULL;	// clear txring.skb_ptr
++	}
++
++	return 0;
++
++err_out:
++	star_nic_buffer_free();
++	return err;
++}
++
++
++#ifdef CONFIG_STAR_JUMBO
++#define MINIMUM_ETHERNET_FRAME_SIZE	64
++#define MAX_JUMBO_FRAME_SIZE		2036
++#define ENET_HEADER_SIZE			14
++#define ETHERNET_FCS_SIZE			4
++#define ETHERNET_VLAN_SIZE			4
++#define NET_IP_ALIGN				2
++static int
++str8100_change_mtu(struct net_device *netdev, int new_mtu)
++{
++printk("%s: new_mtu=%d\n",__FUNCTION__,new_mtu);
++	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE+ETHERNET_VLAN_SIZE;
++	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
++	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
++		printk("%s: Invalid MTU setting (%d)\n",__FUNCTION__,new_mtu);
++		return -EINVAL;
++	}
++	netdev->mtu = new_mtu;
++
++//	star_nic_buffer_free();
++//	star_nic_buffer_alloc();
++
++//	if (netif_running(netdev))
++//		e1000_reinit_locked(adapter);
++
++	return 0;
++
++}
++#endif
++
++#ifdef CONFIG_STAR_NIC_NAPI
++#if 1
++static int star_nic_poll(struct napi_struct *napi, int budget)
++{
++	struct star_nic_private *priv = netdev_priv(STAR_NIC_LAN_DEV);
++        int work_done = 0;
++        int work_to_do = budget;
++
++	star_nic_receive_packet(0, &work_done, work_to_do);
++
++        budget -= work_done;
++
++        /* if no Tx and not enough Rx work done, exit the polling mode */
++        if (work_done) {
++                if (test_bit(0, (unsigned long *)&is_qf) == 1) { // queue full
++                        clear_bit(0, (unsigned long *)&is_qf);
++                        HAL_NIC_RX_DMA_START();
++                        return 1;
++                }
++        } else {
++		napi_complete(&priv->napi);
++#ifdef CONFIG_STAR_NIC_NAPI_MASK_IRQ
++		enable_irq(INTC_NIC_RXRC_BIT_INDEX);
++#endif
++                return 0;
++        }
++
++        return work_done;
++}
++#else
++static int star_nic_poll(struct net_device *netdev, int *budget)
++{
++	struct star_nic_private *priv = netdev_priv(STAR_NIC_LAN_DEV);
++	int work_done = 0;
++	int work_to_do = min(*budget, netdev->quota); // where is min define
++
++	star_nic_receive_packet(0, &work_done, work_to_do);
++
++	*budget -= work_done;
++	netdev->quota -= work_done;
++
++	/* if no Tx and not enough Rx work done, exit the polling mode */
++	if (work_done) {
++		if (test_bit(0, (unsigned long *)&is_qf) == 1) { // queue full
++			clear_bit(0, (unsigned long *)&is_qf);
++			HAL_NIC_RX_DMA_START();
++			return 1;
++		}
++	} else {
++		napi_complete(&priv->napi);
++#ifdef CONFIG_STAR_NIC_NAPI_MASK_IRQ
++		enable_irq(INTC_NIC_RXRC_BIT_INDEX);
++#endif
++		return 0;
++	}
++	return 1;
++}
++#endif
++#endif
++
++static int star_nic_get_rfd_buff(int index)
++{
++	struct star_nic_private *priv;
++	STAR_NIC_RXDESC volatile *rxdesc_ptr;
++	struct sk_buff *skb_ptr;
++	unsigned char *data;
++	int len;
++
++	//TODO: get rxdesc ptr
++	rxdesc_ptr = rxring.vir_addr + index;
++	skb_ptr = rxring.skb_ptr[index];
++#ifdef CONFIG_STAR_JUMBO
++	if (rxdesc_ptr->fs != 1 || rxdesc_ptr->ls != 1) {
++		goto freepacket;
++	}
++#endif
++	len = rxdesc_ptr->length;
++
++	//dma_cache_maintenance(skb_ptr->data, len, PCI_DMA_FROMDEVICE);
++	fa_dma_inv_range(skb_ptr->data, (unsigned long)skb_ptr->data + len);
++
++	data = skb_put(skb_ptr, len);
++
++	skb_ptr->dev = STAR_NIC_LAN_DEV;
++
++	priv = netdev_priv(skb_ptr->dev);
++
++#ifdef STAR_NIC_RX_HW_CHECKSUM
++	if (rxdesc_ptr->ipf == 1 || rxdesc_ptr->l4f == 1) {
++		if (rxdesc_ptr->prot != 0x11) {
++			skb_ptr->ip_summed = CHECKSUM_NONE;
++		} else {
++			// CheckSum Fail
++			priv->stats.rx_errors++;
++			goto freepacket;
++		}
++	} else {
++			skb_ptr->ip_summed = CHECKSUM_UNNECESSARY;
++	}
++#else
++	skb_ptr->ip_summed = CHECKSUM_NONE;
++#endif
++
++	// this line must, if no, packet will not send to network layer
++	skb_ptr->protocol = eth_type_trans(skb_ptr, skb_ptr->dev);
++
++	priv->stats.rx_packets++;
++	priv->stats.rx_bytes += len;
++	skb_ptr->dev->last_rx = jiffies;
++
++	// if netif_rx any package, will let this driver core dump.
++#ifdef CONFIG_STAR_NIC_NAPI
++	netif_receive_skb(skb_ptr);
++#else
++	netif_rx(skb_ptr);
++#endif
++
++	return 0;
++
++freepacket:
++	dev_kfree_skb_any(skb_ptr);
++	return 0;
++}
++
++#ifdef CONFIG_STAR_NIC_NAPI
++void star_nic_receive_packet(int mode, int *work_done, int work_to_do)
++#else
++void star_nic_receive_packet(int mode)
++#endif
++{
++	int rxsd_index;
++	u32 rxsd_current;
++	STAR_NIC_RXDESC volatile *rxdesc_ptr = rxring.vir_addr + rxring.cur_index;
++	struct sk_buff *skb_ptr;
++#ifndef CONFIG_STAR_NIC_NAPI
++	int rxqf = 0; // Queue Full Mode =0
++#endif
++	int i, rxcount = 0;
++	HAL_NIC_READ_RXSD(rxsd_current);
++	rxsd_index = (rxsd_current - (u32)rxring.phy_addr) >> 4;
++
++	if (rxsd_index > rxring.cur_index) {
++		rxcount = rxsd_index - rxring.cur_index;
++	} else if (rxsd_index < rxring.cur_index) {
++		rxcount = (STAR_NIC_MAX_RFD_NUM - rxring.cur_index) + rxsd_index;
++	} else {
++		if (rxdesc_ptr->cown == 0) {
++			goto receive_packet_exit;
++		} else {
++			// Queue Full
++#ifndef CONFIG_STAR_NIC_NAPI
++			rxqf = 1;
++#endif
++			rxcount = STAR_NIC_MAX_RFD_NUM;
++		}
++	}
++
++#ifndef CONFIG_STAR_NIC_NAPI
++	if (mode == 1) {
++		rxqf = 1;
++		rxcount = STAR_NIC_MAX_RFD_NUM;
++	}
++#endif
++
++	for (i = 0; i < rxcount; i++) {
++#ifdef CONFIG_STAR_NIC_NAPI
++		if (*work_done >= work_to_do)
++			break;
++		++(*work_done);
++#endif
++		if (rxdesc_ptr->cown != 0) {
++			// Alloc New skb_buff 
++			skb_ptr = star_nic_alloc_skb();
++			// Check skb_buff
++			if (skb_ptr != NULL) {
++				star_nic_get_rfd_buff(rxring.cur_index);
++				rxring.skb_ptr[rxring.cur_index] = skb_ptr;
++				rxdesc_ptr->data_ptr	= (u32)virt_to_phys(skb_ptr->data);
++				rxdesc_ptr->length	= MAX_PACKET_LEN;	
++				rxdesc_ptr->cown	= 0; // set cbit to 0 for CPU Transfer	
++			} else {
++				// TODO:
++				// I will add dev->lp.stats->rx_dropped, it will effect the performance
++				DBG_PRINT("%s: Alloc sk_buff fail, reuse the buffer\n", __FUNCTION__);
++				rxdesc_ptr->cown	= 0; // set cbit to 0 for CPU Transfer	
++				return;
++			}
++		} else {
++			//printk("[KC_DEBUG] star_nic_receive_packet() encounter COWN==0 BUG\n");
++		}
++
++		if (rxring.cur_index == (STAR_NIC_MAX_RFD_NUM - 1)) {
++			rxring.cur_index	= 0;
++			rxdesc_ptr		= rxring.vir_addr;
++		} else {
++			rxring.cur_index++;
++			rxdesc_ptr++;
++		}
++	}
++
++#ifndef CONFIG_STAR_NIC_NAPI
++	if (rxqf) {
++		rxring.cur_index = rxsd_index;
++		mb();
++		HAL_NIC_RX_DMA_START();
++	}
++#endif
++
++receive_packet_exit:
++	return;
++}
++
++#ifdef FREE_TX_SKB_MULTI
++#define FREE_TX_SKB_MULTI_MAX   16
++#define MAX_TX_SKB_FREE_NUM     FREE_TX_SKB_MULTI_MAX + MAX_SKB_FRAGS
++#endif
++
++#define FIX_NFS
++static int star_nic_send_packet(struct sk_buff *skb, struct net_device *dev)
++{
++#if defined(STAR_NIC_TX_HW_CHECKSUM) && defined(MAX_SKB_FRAGS) && defined(STAR_NIC_SG)
++	struct star_nic_private *priv = netdev_priv(dev);
++	STAR_NIC_TXDESC volatile *txdesc_ptr;
++	unsigned long flags;
++
++#ifdef FREE_TX_SKB_MULTI
++	int i;
++	int tssd_index;
++	int tssd_current;
++	int skb_free_count = 0;
++	struct sk_buff *skb_free[MAX_TX_SKB_FREE_NUM];
++#endif
++
++#if defined(STAR_NIC_TX_HW_CHECKSUM) && defined(MAX_SKB_FRAGS) && defined(STAR_NIC_SG)
++	int org_index;
++	int cur_index;
++
++
++	unsigned int f;
++	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
++	unsigned int len = skb->len - skb->data_len;
++	int padding_size = ETH_ZLEN - len;
++	unsigned int offset;
++
++
++#ifndef FREE_TX_SKB_MULTI
++	int skb_free_count = 0;
++	struct sk_buff *skb_free[MAX_SKB_FRAGS];
++#endif
++#else
++#ifndef FREE_TX_SKB_MULTI
++	struct sk_buff *skb_free;
++#endif
++#endif
++
++	spin_lock_irqsave(&star_nic_send_lock, flags);
++
++#ifdef FREE_TX_SKB_MULTI
++		int count = 0;
++
++		for (i = 0; i < FREE_TX_SKB_MULTI_MAX; i++) {
++			txdesc_ptr = txring.vir_addr + txring.to_free_index;
++			if (txdesc_ptr->cown == 0) {
++				break;
++			}
++			if (txring.skb_ptr[txring.to_free_index]) {
++				skb_free[count++] = txring.skb_ptr[txring.to_free_index];
++				txring.skb_ptr[txring.to_free_index] = NULL;
++			}
++
++			increase_cyclic(txring.to_free_index, STAR_NIC_MAX_TFD_NUM);
++
++			if (count == FREE_TX_SKB_MULTI_MAX) {
++				break;
++			}
++		}
++		skb_free_count = count;
++#endif
++
++#if defined(STAR_NIC_TX_HW_CHECKSUM) && defined(MAX_SKB_FRAGS) && defined(STAR_NIC_SG)
++	org_index = txring.cur_index;
++	cur_index = txring.cur_index;
++	for (f = 0; f < (nr_frags + 1); f++) {
++		txdesc_ptr = txring.vir_addr + cur_index;
++
++		if (txdesc_ptr->cown == 0) {
++			spin_unlock_irqrestore(&star_nic_send_lock, flags);
++#ifdef FREE_TX_SKB_MULTI
++			for (i = 0; i < skb_free_count; i++) {
++				dev_kfree_skb(skb_free[i]);
++			}
++#endif
++			/* Not enough tx buffer, re-queue the skb.             */
++			return NETDEV_TX_BUSY;
++		}
++
++		if (txring.skb_ptr[cur_index]) {
++			skb_free[skb_free_count++] = txring.skb_ptr[cur_index];
++		}
++
++#if defined(FREE_TX_SKB_MULTI) || defined(STAR_NIC_TIMER)
++		if(cur_index==txring.to_free_index)
++			increase_cyclic(txring.to_free_index, STAR_NIC_MAX_TFD_NUM);
++#endif
++
++		if (f == 0) {
++			txdesc_ptr->fs		= 1;
++		} else {
++			txdesc_ptr->fs		= 0;
++		}
++		if (f == nr_frags) {
++			txdesc_ptr->ls		= 1;
++		} else {
++			txdesc_ptr->ls		= 0;
++		}
++
++		increase_cyclic(cur_index, STAR_NIC_MAX_TFD_NUM);
++	}
++
++	txdesc_ptr = (txring.vir_addr + txring.cur_index);
++	txdesc_ptr->data_ptr			= virt_to_phys(skb->data);
++
++	if ((nr_frags == 0) && (len < PKT_MIN_SIZE)) {
++		txdesc_ptr->length		= PKT_MIN_SIZE;
++		memset(skb->data + len, 0x00, PKT_MIN_SIZE - len);
++	} else {
++		txdesc_ptr->length		= len;
++	}
++
++	if (nr_frags) {
++		txring.skb_ptr[txring.cur_index]	= NULL;
++	} else {
++		txring.skb_ptr[txring.cur_index]	= skb;
++	}
++	//dma_cache_maintenance(skb->data, txdesc_ptr->length, PCI_DMA_TODEVICE);
++	fa_dma_clean_range(skb->data, (unsigned long)skb->data + txdesc_ptr->length);
++
++	increase_cyclic(txring.cur_index, STAR_NIC_MAX_TFD_NUM);
++
++	for (f = 0; f < nr_frags; f++) {
++		struct skb_frag_struct *frag; 
++		txdesc_ptr = txring.vir_addr + txring.cur_index;
++		frag = &skb_shinfo(skb)->frags[f]; 
++#if 1
++		padding_size -= frag->size;
++
++		//txdesc_ptr->data_ptr = virt_to_phys(page_address(frag->page) + frag->page_offset);
++		txdesc_ptr->data_ptr = virt_to_phys(sg_virt(frag));
++		txdesc_ptr->length = frag->size;
++#else
++		len = frag->size; 
++		//offset = frag->page_offset; 
++
++		//txdesc_ptr->data_ptr = virt_to_phys(page_address(frag->page) + offset);
++		txdesc_ptr->data_ptr = virt_to_phys(sg_virt(frag));
++		txdesc_ptr->length = len;
++#endif // FIX_NFS
++
++		if (f == (nr_frags - 1)) {
++			txring.skb_ptr[txring.cur_index] = skb;
++		} else {
++			txring.skb_ptr[txring.cur_index] = NULL;
++		}
++		//dma_cache_maint(page_address(frag->page) + offset, txdesc_ptr->length, PCI_DMA_TODEVICE);
++		// dma_cache_maintenance(sg_virt(frag), txdesc_ptr->length, PCI_DMA_TODEVICE);
++		fa_dma_clean_range(sg_virt(frag), (unsigned long)sg_virt(frag)+txdesc_ptr->length);
++
++		increase_cyclic(txring.cur_index, STAR_NIC_MAX_TFD_NUM);
++		
++		if (padding_size > 0)
++		/* Padding zero to the end of packet to meet minimum 
++		 * packet size requirement.                       */
++			txdesc_ptr->length += padding_size;
++	}
++
++	for (f = 0; f < (nr_frags + 1); f++) {
++		txdesc_ptr = txring.vir_addr + org_index;
++		txdesc_ptr->cown = 0;
++		org_index++;
++		if (org_index == STAR_NIC_MAX_TFD_NUM) {
++			org_index = 0;
++		}
++	}
++
++
++
++#else
++	txdesc_ptr = txring.vir_addr + txring.cur_index;
++
++	if (txdesc_ptr->cown == 0) { // This TFD is busy
++		spin_unlock_irqrestore(&star_nic_send_lock, flags);
++		// re-queue the skb
++		return 1;
++	}
++
++#ifndef FREE_TX_SKB_MULTI
++	if (txring.skb_ptr[txring.cur_index]) {
++		// MUST TODO: Free skbuff
++		skb_free = txring.skb_ptr[txring.cur_index];
++	}
++#endif
++
++	txdesc_ptr->fs		= 1;
++	txdesc_ptr->ls		= 1;
++
++	txring.skb_ptr[txring.cur_index]	= skb;
++	txdesc_ptr->data_ptr			= virt_to_phys(skb->data);
++	if (skb->len < PKT_MIN_SIZE) {
++		txdesc_ptr->length		= PKT_MIN_SIZE;
++		memset(skb->data + skb->len, 0x00, PKT_MIN_SIZE - skb->len);
++	} else {
++		txdesc_ptr->length		= skb->len;
++	}
++
++	//dma_cache_maintenance(skb->data, txdesc_ptr->length, PCI_DMA_TODEVICE);
++	fa_dma_clean_range(skb->data, (unsigned long)skb->data+txdesc_ptr->length);
++
++	increase_cyclic(txring.cur_index, STAR_NIC_MAX_TFD_NUM);
++
++	txdesc_ptr->cown	= 0;
++#endif
++
++	mb();
++	HAL_NIC_TX_DMA_START();
++
++	priv->stats.tx_packets++;
++	priv->stats.tx_bytes += skb->len;
++	dev->trans_start = jiffies;
++
++	spin_unlock_irqrestore(&star_nic_send_lock, flags);
++
++#ifdef FREE_TX_SKB_MULTI
++	for (i = 0; i < skb_free_count; i++) {
++		dev_kfree_skb(skb_free[i]);
++	}
++#else
++#if defined(STAR_NIC_TX_HW_CHECKSUM) && defined(MAX_SKB_FRAGS) && defined(STAR_NIC_SG)
++	for (f = 0; f < skb_free_count; f++) {
++		dev_kfree_skb(skb_free[f]);
++	}
++#else
++	if (skb_free) {
++		dev_kfree_skb(skb_free);
++	}
++#endif
++#endif
++
++	return NETDEV_TX_OK;
++
++#else
++	struct star_nic_private *priv = netdev_priv(dev);
++	STAR_NIC_TXDESC volatile *txdesc_ptr = (txring.vir_addr + txring.cur_index);
++	struct sk_buff *skb_free = NULL;
++	unsigned long flags;
++
++	spin_lock_irqsave(&star_nic_send_lock, flags);
++
++	if (txdesc_ptr->cown == 0) { // This TFD is busy
++		spin_unlock_irqrestore(&star_nic_send_lock, flags);
++		// re-queue the skb
++		return NETDEV_TX_BUSY;
++	}
++
++	if (txdesc_ptr->data_ptr != 0) {
++		// MUST TODO: Free skbuff
++		skb_free = txring.skb_ptr[txring.cur_index];
++#ifdef STAR_NIC_TIMER
++		txring.to_free_index = txring.cur_index + 1;
++		if (txring.to_free_index == STAR_NIC_MAX_TFD_NUM) {
++			txring.to_free_index = 0;
++		}
++#endif
++	}
++
++#ifdef STAR_NIC_TX_HW_CHECKSUM
++	if (skb->protocol == __constant_htons(ETH_P_IP)) {
++		if (skb->nh.iph->protocol == IPPROTO_UDP) {
++			txdesc_ptr->uco = 1;
++			txdesc_ptr->tco = 0;
++			//printk("[KC DEBUG] UDP PACKET\n");
++		} else if (skb->nh.iph->protocol == IPPROTO_TCP) {
++			txdesc_ptr->uco = 0;
++			txdesc_ptr->tco = 1;
++			//printk("[KC DEBUG] TCP PACKET\n");
++		} else {
++			txdesc_ptr->uco = 0;
++			txdesc_ptr->tco = 0;
++			//printk("[KC DEBUG] NOT TCP&UDP PACKET\n");
++		}
++	} else {
++#if 0
++		if (skb->protocol == __constant_htons(ETH_P_ARP)) {
++			printk("[KC DEBUG] ARP PACKET\n");
++		} else {
++			printk("[KC DEBUG] NOT IP PACKET\n");
++		}
++#endif
++		txdesc_ptr->ico = 0;
++		txdesc_ptr->uco = 0;
++		txdesc_ptr->tco = 0;
++	}
++#endif
++
++	txring.skb_ptr[txring.cur_index]	= skb;
++	txdesc_ptr->data_ptr			= virt_to_phys(skb->data);
++	if (skb->len < PKT_MIN_SIZE) {
++		txdesc_ptr->length		= PKT_MIN_SIZE;
++		memset(skb->data + skb->len, 0x00, PKT_MIN_SIZE - skb->len);
++	} else {
++		txdesc_ptr->length		= skb->len;
++	}
++
++	//dma_cache_maintenance(skb->data, txdesc_ptr->length, PCI_DMA_TODEVICE);
++	fa_dma_clean_range(skb->data, (unsigned long)skb->data+txdesc_ptr->length);
++
++	txdesc_ptr->fs		= 1;
++	txdesc_ptr->ls		= 1;
++	// Wake interrupt
++	txdesc_ptr->intr	= 0;
++	txdesc_ptr->cown	= 0;
++
++	mb();
++	HAL_NIC_TX_DMA_START();
++
++	priv->stats.tx_packets++;
++	priv->stats.tx_bytes += skb->len;
++	dev->trans_start = jiffies;
++
++	if (txring.cur_index == (STAR_NIC_MAX_TFD_NUM - 1)) {
++		txring.cur_index = 0;
++	} else {
++		txring.cur_index++;
++	}
++
++	spin_unlock_irqrestore(&star_nic_send_lock, flags);
++	if (skb_free) {
++		dev_kfree_skb(skb_free);
++	}
++
++#ifdef STAR_NIC_TIMER
++	mod_timer(&star_nic_timer, jiffies + 10);
++#endif
++	return NETDEV_TX_OK;
++#endif
++}
++
++static void star_nic_set_mac_addr(struct net_device *dev, const char *mac_addr)
++{
++	memcpy(dev->dev_addr, mac_addr, 6);
++
++	NIC_MY_MAC_HIGH_BYTE_REG =
++	       	(mac_addr[0] << 8) |
++		 mac_addr[1];
++
++	NIC_MY_MAC_LOW_BYTE_REG =
++	       	(mac_addr[2] << 24) |
++		(mac_addr[3] << 16) |
++		(mac_addr[4] << 8)  |
++		(mac_addr[5]);
++
++	printk("MAC Addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
++		mac_addr[0],
++		mac_addr[1],
++		mac_addr[2],
++		mac_addr[3],
++		mac_addr[4],
++		mac_addr[5]);
++}
++
++static int star_nic_set_lan_mac_addr(struct net_device *dev, void *addr)
++{
++	struct sockaddr *sock_addr = addr;
++	struct star_nic_private *priv = netdev_priv(dev);
++
++	spin_lock_irq(&priv->lock);
++	star_nic_set_mac_addr(dev, sock_addr->sa_data);
++	spin_unlock_irq(&priv->lock);
++
++	return 0;
++}
++
++
++#ifdef CONFIG_PM
++static int nic_suspended=0;
++void inline str8100_wol_enter(){
++
++	//stop tx dma
++	HAL_NIC_TX_DMA_STOP();
++	//Enable Internal Loopback mode
++	NIC_TEST_1_REG|=(0x1<<18);
++
++	//WoL
++	NIC_MAC_CONTROL_REG |= (0x1 << 30); //assert WoL bit
++
++
++	while (!((NIC_MAC_CONTROL_REG>>29)&0x1)){
++		udelay(500);
++		NIC_MAC_CONTROL_REG |= (0x1 << 30); //assert WoL bit
++		NIC_MAC_CONTROL_REG &= ~(0x1 << 30); //de-assert WoL bit
++		NIC_MAC_CONTROL_REG |= (0x1 << 30); //assert WoL bit
++		udelay(500);
++
++//		if((NIC_TEST_1_REG&(0x1fff))!=4096){
++//printk("%.8x\n",NIC_TEST_1_REG);
++			u32 test=0;
++			test=test=NIC_TEST_1_REG;
++//		}
++	}
++	//Disable Internal Loopback mode
++	NIC_TEST_1_REG&=~(0x1<<18);
++
++	//Enable Magic packet received of Nic status Int	
++	HAL_NIC_ENABLE_INTERRUPT_STATUS_SOURCE_BIT(4);
++
++	NIC_MAC_CONTROL_REG |= (0x1 <<29);//write "1" clear
++	HAL_PWRMGT_DISABLE_NIC_CLOCK();
++}
++
++void inline str8100_wol_exit(){
++	HAL_NIC_DISABLE_INTERRUPT_STATUS_SOURCE_BIT(4);
++	HAL_PWRMGT_ENABLE_NIC_CLOCK();
++	NIC_MAC_CONTROL_REG &= ~(0x1 << 30); //de-assert power down bit
++
++	HAL_NIC_CLEAR_INTERRUPT_STATUS_SOURCES((0x1<<4));
++	HAL_NIC_TX_DMA_START();
++}
++
++int inline str8100_nic_suspend(suspend_state_t state)
++{
++	if(!netif_running(STAR_NIC_LAN_DEV)) return 0;
++	nic_suspended=1;
++
++#ifdef CONFIG_PM_DEBUG
++	printk("%s:\n",__FUNCTION__);
++#endif
++	netif_device_detach(STAR_NIC_LAN_DEV);
++/*
++	if (netif_running(STAR_NIC_LAN_DEV)) {
++		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
++		e1000_down(adapter);
++	}
++*/
++	str8100_wol_enter();
++	return 0;
++}
++int inline str8100_nic_resume()
++{
++	//Waked
++	if(!nic_suspended) return 0;
++	nic_suspended=0;
++#ifdef CONFIG_PM_DEBUG
++	printk("%s:\n",__FUNCTION__);
++#endif
++/*	if (netif_running(STAR_NIC_LAN_DEV))
++		e1000_up(adapter);
++*/
++	netif_device_attach(STAR_NIC_LAN_DEV);
++
++	str8100_wol_exit();	
++
++	return 0;
++}
++#endif
++
++static int star_nic_init(struct net_device *dev)
++{
++#if 1
++	// set hight
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
++	// set low
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1 << 15);
++	// set high
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
++#endif
++
++#if 1
++	// set NIC clock to 67.5MHz
++	PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 7);
++#else
++	// set NIC clock to 125MHz
++	PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x1 << 7);
++#endif
++
++	// enable NIC clock
++	HAL_PWRMGT_ENABLE_NIC_CLOCK();
++	//NIC_MAC_CONTROL_REG = 0x00527C00;
++	udelay(100);
++
++	// Configure GPIO for NIC MDC/MDIO pins
++	HAL_MISC_ENABLE_MDC_MDIO_PINS();
++	HAL_MISC_ENABLE_NIC_COL_PINS();
++#ifdef CONFIG_STAR_NIC_PHY_INTERNAL_PHY
++	MISC_GPIOA_PIN_ENABLE_REG |= (0x7 << 22);
++	MISC_FAST_ETHERNET_PHY_CONFIG_REG |=  (FE_PHY_LED_MODE >> 12) & 0x3;
++
++	// set hight
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
++	// set low
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1 << 15);
++	// set high
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
++#else
++	//Enable GPIO for NIC LED
++	HAL_MISC_ENABLE_LED012_PINS();
++#endif
++
++	// disable all interrupt status sources
++	HAL_NIC_DISABLE_ALL_INTERRUPT_STATUS_SOURCES();
++
++	// clear previous interrupt sources
++	HAL_NIC_CLEAR_ALL_INTERRUPT_STATUS_SOURCES();
++
++	// disable all DMA-related interrupt sources
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_TXTC_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXRC_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_TXQE_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXQF_BIT_INDEX);
++
++	// clear previous interrupt sources
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_NIC_TXTC_BIT_INDEX);
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_NIC_RXRC_BIT_INDEX);
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_NIC_TXQE_BIT_INDEX);
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_NIC_RXQF_BIT_INDEX);
++
++	HAL_NIC_TX_DMA_STOP();
++	HAL_NIC_RX_DMA_STOP();
++
++	if (star_nic_buffer_alloc() != 0) {
++		return -1;
++	}
++	star_nic_mac_config(dev);
++	star_nic_fc_config(dev);
++
++	if (star_nic_phy_config(dev) != 0) {
++		star_nic_buffer_free();
++		return -1;
++	}
++
++	star_nic_vlan_config(dev);
++	star_nic_arl_config(dev);
++
++	/* MAC address is already in MAC registers from TS-BOOTROM */
++	default_mac_addr[0] = NIC_MY_MAC_HIGH_BYTE_REG >> 8;
++	default_mac_addr[1] = NIC_MY_MAC_HIGH_BYTE_REG;
++	default_mac_addr[2] = NIC_MY_MAC_LOW_BYTE_REG >> 24;
++	default_mac_addr[3] = NIC_MY_MAC_LOW_BYTE_REG >> 16;
++	default_mac_addr[4] = NIC_MY_MAC_LOW_BYTE_REG >> 8;
++	default_mac_addr[5] = NIC_MY_MAC_LOW_BYTE_REG;
++
++	star_nic_set_mac_addr(dev, default_mac_addr);
++	star_nic_mib_reset();
++
++	*(u32 volatile *)(SYSVA_MISC_BASE_ADDR+0x0c) = 0x00000125;    //0x00000105 pb0_nic
++
++	HAL_NIC_WRITE_TXSD(txring.phy_addr);
++	HAL_NIC_WRITE_TX_BASE(txring.phy_addr);
++	HAL_NIC_WRITE_RXSD(rxring.phy_addr);
++	HAL_NIC_WRITE_RX_BASE(rxring.phy_addr);
++
++	star_nic_dma_config(dev);
++
++	return 0;
++}
++
++static void set_multicast_list(struct net_device *dev) {
++}
++
++static const struct net_device_ops star_ops = {
++        .ndo_open               = star_nic_lan_open,
++        .ndo_stop               = star_nic_close,
++        .ndo_start_xmit         = star_nic_send_packet,
++        .ndo_get_stats          = star_nic_get_stats,
++        .ndo_set_multicast_list = set_multicast_list,
++        .ndo_tx_timeout         = star_nic_timeout,
++        .ndo_change_mtu         = eth_change_mtu,
++        .ndo_set_mac_address    = star_nic_set_lan_mac_addr,
++        .ndo_validate_addr      = eth_validate_addr,
++};
++
++static int __init star_nic_probe(int port_type)
++{
++	struct net_device *netdev;
++	struct star_nic_private *priv;
++	int err;
++
++	netdev = alloc_etherdev(sizeof(struct star_nic_private));
++	if (!netdev) {
++		err = -ENOMEM;
++		goto err_alloc_etherdev;
++	}
++
++	priv = netdev_priv(netdev);
++	memset(priv, 0, sizeof(struct star_nic_private));
++	spin_lock_init(&priv->lock);
++
++	netdev->base_addr		= SYSVA_NIC_BASE_ADDR;
++	netdev->netdev_ops = &star_ops;
++
++#if defined(STAR_NIC_TX_HW_CHECKSUM) && defined(MAX_SKB_FRAGS) && defined(STAR_NIC_SG)
++	netdev->features                = NETIF_F_IP_CSUM | NETIF_F_SG;
++#elif defined(STAR_NIC_TX_HW_CHECKSUM)
++	netdev->features                = NETIF_F_IP_CSUM;
++#endif
++#ifdef CONFIG_STAR_NIC_NAPI
++	netif_napi_add(netdev, &priv->napi, star_nic_poll, 64);
++#else
++	netdev->poll			= star_nic_poll;
++	netdev->weight			= 64;
++#endif
++	priv->dev_index			= LAN_PORT;
++
++#ifdef CONFIG_STAR_JUMBO
++	#error fix me
++	netdev->change_mtu = &str8100_change_mtu;
++#endif
++
++	err = register_netdev(netdev);
++	if (err) {
++		goto err_register_netdev;
++	}
++
++	//SET_MODULE_OWNER(netdev);
++
++	STAR_NIC_LAN_DEV = netdev;
++
++	if ((err = star_nic_init(netdev))) {
++		goto err_nic_init;
++	}
++
++	return 0;
++
++err_register_netdev:
++	free_netdev(netdev);
++	return err;
++
++err_nic_init:
++	unregister_netdev(netdev);
++	return err;
++
++err_alloc_etherdev:
++	return err;
++}
++
++static int __init star_nic_lan_init(void)
++{
++	return star_nic_probe(LAN_PORT);
++}
++
++static int __init star_nic_proc_init(void)
++{
++	star_nic_proc_entry = create_proc_entry("str8100/nic", S_IFREG | S_IRUGO, NULL);
++	if (star_nic_proc_entry) {
++		star_nic_proc_entry->read_proc = star_nic_read_proc;
++		star_nic_proc_entry->write_proc = star_nic_write_proc;
++	}
++
++	return 0;
++}
++
++static int __init star_nic_init_module(void)
++{
++	int err = 0;
++
++	printk(KERN_INFO "%s", star_nic_driver_version);
++	spin_lock_init(&star_nic_send_lock);
++	err = star_nic_lan_init();
++	if (err != 0) {
++		return err;
++	}
++	star_nic_proc_init();
++
++	printk("\n");
++#ifdef CONFIG_INTERNEL_PHY_PATCH
++	printk("%s: internal phy patch included.\n",__FUNCTION__);
++	//str813x_internal_phy_proc_init();
++#elif defined(CONFIG_STAR_NIC_PHY_INTERNAL_PHY)
++	printk("%s: internal phy used but no patch included.\n",__FUNCTION__);
++#endif
++#if defined(STAR_NIC_TX_HW_CHECKSUM) && defined(MAX_SKB_FRAGS) && defined(STAR_NIC_SG)
++	printk("%s: scatter/gather enabled.\n",__FUNCTION__);
++#else
++	printk("%s: scatter/gather disabled.\n",__FUNCTION__);
++#endif
++	printk("\n");
++
++#ifdef STAR_NIC_TIMER
++	init_timer(&star_nic_timer);
++	star_nic_timer.function = &star_nic_timer_func;
++	star_nic_timer.data = (unsigned long)NULL;
++#endif
++
++	return 0;
++}
++
++module_init(star_nic_init_module);
++
++//========================================================
++#ifdef CONFIG_INTERNEL_PHY_PATCH
++
++static void (*phy_statemachine)(int, int, int);
++
++#define ETH3220_PHY_MON_PERIOD INTERNAL_PHY_PATCH_CHECK_PERIOD
++
++/*===================================================================================*/
++/*  phy monitor state  */
++#define NUM_PHY 1
++#define PHY_STATE_INIT					0
++#define LINK_DOWN_POSITIVE				1
++#define WAIT_LINK_UP_POSITIVE				2
++#define LINK_UP_POSITIVE				3
++#define WAIT_BYPASS_LINK_UP_POSITIVE			4
++#define BYPASS_AND_LINK_UP_POSITIVE			5
++#define LINK_UP_8101_POSITIVE				6
++#define WAIT_8101_LINK_UP_POSITIVE			7
++
++#define PHY_STATE_LAST					(WAIT_8101_LINK_UP_POSITIVE+1)
++/*===================================================================================*/
++/*  time setting  */
++#define WAIT_BYPASS_LINK_UP_POSITIVE_TIMEOUT		5000	/*  5000 ms  */
++#define WAIT_BYPASS_LINK_UP_NEGATIVE_TIMEOUT		5000	/*  5000 ms  */
++#define LINK_DOWN_ABILITY_DETECT_TIMEOUT		5000	/*  5000 ms  */
++#define DETECT_8101_PERIOD				7000	/*  7000 ms  */
++#define WAIT_8101_LINK_UP_TIMEOUT			3000	/*  3000 ms  */
++
++#define MAX_PHY_PORT					1
++#define DEFAULT_AGC_TRAIN				16
++#define MAX_AGC_TRAIN					16	//train 16 times
++static int agc_train_num = DEFAULT_AGC_TRAIN;
++u32 port_displaybuf[NUM_PHY][MAX_AGC_TRAIN + 1] = {{0}};
++
++static int cuv[3][3] = {
++	{1, 1, 4},
++	{1, 1, 0},
++	{1, 1, -4}};
++static u32 link_status_old = 0;
++//static int agc_th[2] = {0x18, 0x28}; /* To be deleted */
++//static u32 phy_mon_timer; /* To be deleted */
++//static u32 current_agc = 0;   //0:Not patch, 1:patch
++/*===================================================================================*/
++
++typedef struct eth3220_phy_s {
++	u16 state;
++	u16 linkdown_cnt;
++	u32 state_time;
++	u32 timer;
++} eth3220_phy_t;
++
++#define DEBUG_PHY_STATE_TRANSITION			1
++#if DEBUG_PHY_STATE_TRANSITION
++/*  show state transition of debug phy port.
++ *  -1 for all ports
++ *  -2 for disable all ports
++ *  0 - 4 for each port  */
++static int debug_phy_port = -2;
++static char *phystate_name[] = {
++	"init",			/*  PHY_STATE_INIT  */
++	"ldp",			/*  LINK_DOWN_POSITIVE  */
++	"wait_lup",		/*  WAIT_LINK_UP_POSITIVE  */
++	"lup",			/*  LINK_UP_POSITIVE  */
++	"wait_bp_lup",		/*  WAIT_BYPASS_LINK_UP_POSITIVE  */
++	"bp_lup",		/*  BYPASS_AND_LINK_UP_POSITIVE  */
++	"8101_lup",		/*  LINK_UP_8101_POSITIVE  */
++	"wait_8101_lup",	/*  WAIT_8101_LINK_UP_POSITIVE  */
++	"err",
++};
++#endif  /*  DEBUG_PHY_STATE_TRANSITION  */
++static eth3220_phy_t phy[5] = { {PHY_STATE_INIT, 0, 0, 0},
++				{PHY_STATE_INIT, 0, 0, 0},
++				{PHY_STATE_INIT, 0, 0, 0},
++				{PHY_STATE_INIT, 0, 0, 0},
++				{PHY_STATE_INIT, 0, 0, 0}};
++
++static u16 long_cable_global_reg[32]={
++0x0000,0x19a0,0x1d00,0x0e80,0x0f60,0x07c0,0x07e0,0x03e0,
++0x0000,0x0000,0x0000,0x2000,0x8250,0x1700,0x0000,0x0000,
++0x0000,0x0000,0x0000,0x0000,0x0000,0x204b,0x01c2,0x0000,
++0x0000,0x0000,0x0fff,0x4100,0x9319,0x0021,0x0034,0x270a|FE_PHY_LED_MODE
++};
++
++static u16 long_cable_local_reg[32]={
++0x3100,0x786d,0x01c1,0xca51,0x05e1,0x45e1,0x0003,0x001c,
++0x2000,0x9828,0xf3c4,0x400c,0xf8ff,0x6940,0xb906,0x503c,
++0x8000,0x297a,0x1010,0x5010,0x6ae1,0x7c73,0x783c,0xfbdf,
++0x2080,0x3244,0x1301,0x1a80,0x8e8f,0x8000,0x9c29,0xa70a|FE_PHY_LED_MODE
++};
++
++static void internal_phy_update(unsigned long data)
++{
++	internal_phy_patch_check(0);
++	mod_timer(&internal_phy_timer, jiffies + INTERNAL_PHY_PATCH_CHECK_PERIOD / 10);
++}
++
++static struct timer_list internal_phy_timer =
++	TIMER_INITIALIZER(internal_phy_update, 0, 0);
++
++/*=============================================================*
++ *  eth3220ac_rt8101_phy_setting
++ *=============================================================*/
++static  void eth3220ac_rt8101_phy_setting(int port)
++{
++	star_nic_write_phy(port, 12, 0x18ff);
++	star_nic_write_phy(port, 18, 0x6400);
++}
++
++static void eth3220ac_release_bpf(int port)
++{
++	star_nic_write_phy(port, 18, 0x6210);
++}
++
++static  void eth3220ac_def_bpf(int port)
++{
++	star_nic_write_phy(port, 18, 0x6bff);
++}
++
++static  void eth3220ac_def_linkdown_setting(int port)
++{
++	star_nic_write_phy(port, 13, 0xe901);
++	star_nic_write_phy(port, 14, 0xa3c6);
++}
++
++static  void eth3220ac_def_linkup_setting(int port)
++{
++	star_nic_write_phy(port, 13, 0x6901);
++	star_nic_write_phy(port, 14, 0xa286);
++}
++
++/*=============================================================*
++ *  eth3220ac_link_agc:
++ *=============================================================*/
++static int eth3220ac_link_agc(int port, int speed)
++{
++	u16 reg;
++	u32 agc_data = 0;
++	u32 short_cable;
++	int i, jj;
++
++	/* if speed = 100MHz, then continue */
++	if (speed == 0)
++		return 0;
++
++	short_cable = 0;
++	jj = 0;
++	for (i=0; i < agc_train_num; i++) {
++		star_nic_read_phy(port, 15, &reg);
++		reg &= 0x7f;
++		if (reg <= 0x12) {
++			short_cable = 1;
++			jj++;
++			agc_data += (u32)reg;
++		}
++	}
++	if (short_cable) {
++		agc_data = (agc_data / jj) + 4;
++	} else {
++		agc_data = (cuv[2][0] * agc_data) / cuv[2][1] / agc_train_num - 4;
++	}
++
++	/*  Fix AGC  */
++	agc_data = 0xd0 | (agc_data << 9);
++	star_nic_write_phy(port, 15, agc_data);
++	udelay(1000);
++	star_nic_read_phy(port, 15, &reg);
++	reg &= ~(0x1 << 7);
++	star_nic_write_phy(port, 15, reg);
++
++	return 0;
++}
++
++/*=============================================================*
++ *  eth3220ac_unlink_agc:
++ *=============================================================*/
++static void eth3220ac_unlink_agc(int port)
++{
++	// start AGC adaptive
++	star_nic_write_phy(port, 15, 0xa050);
++}
++
++/*=============================================================*
++ *  eth3220ac_rt8100_check
++ *=============================================================*/
++static int eth3220ac_rt8100_check(int port)
++{
++	u16 reg, reg2;
++
++	/* Read reg27 (error register) */
++	star_nic_read_phy(port, 27, &reg);
++	/* if error exists, set Bypass Filter enable */
++	if ((reg & 0xfffc)) {
++                star_nic_read_phy(port, 15, &reg);	
++                star_nic_read_phy(port, 27, &reg2);	
++		if (( reg2 & 0xfffc) && (((reg >> 9) & 0xff) < 0x1c)) {
++			printk("8100 pos err\n");
++			/* Bypass agcgain disable */
++			star_nic_write_phy(port, 15, (reg & (~(0x1 << 7))));
++			
++			/* repeat counts when reaching threshold error */
++			star_nic_write_phy(port, 13, 0x4940);
++			
++			/* Speed up AN speed && compensate threshold phase error */
++			star_nic_write_phy(port, 14, 0xa306);
++			
++			/* Bypass Filter enable */
++                        star_nic_read_phy(port, 18, &reg2);	
++
++			star_nic_write_phy(port, 18, (reg | 0x400));
++			
++			/* restart AN */
++			star_nic_write_phy(port, 0, 0x3300);
++			return 1;
++		}
++	}
++	return 0;
++}
++
++
++/*=============================================================*
++ *  eth3220ac_rt8100_linkdown
++ *=============================================================*/
++static void eth3220ac_rt8100_linkdown(int port)
++{
++	u16 reg;
++	
++	/* Bypass Filter disable */
++	star_nic_read_phy(port, 18, &reg);	
++	star_nic_write_phy(port, 18, (reg & (~(0x1 << 10))));
++	eth3220ac_def_linkdown_setting(port);
++}
++
++static void eth3220ac_normal_phy_setting(int port)
++{
++	star_nic_write_phy(port, 12, 0xd8ff);
++	eth3220ac_def_bpf(port);
++}
++
++/*=============================================================*
++ *  wp3220ac_phystate
++ *=============================================================*/
++static void wp3220ac_phystate(int port, int link, int speed)
++{
++	int next_state;
++	u16 reg, reg2;	
++
++	phy[port].timer += ETH3220_PHY_MON_PERIOD;
++	
++	if (link) {
++		/*  Link up state  */
++		switch(phy[port].state) {
++		case LINK_UP_POSITIVE:
++			next_state = eth3220ac_rt8100_check(port) ?
++				WAIT_BYPASS_LINK_UP_POSITIVE :
++				LINK_UP_POSITIVE;
++			break;
++			
++		case PHY_STATE_INIT:
++		case WAIT_LINK_UP_POSITIVE:
++		case LINK_DOWN_POSITIVE:
++			next_state = LINK_UP_POSITIVE;
++			eth3220ac_def_linkup_setting(port);
++			eth3220ac_link_agc(port, speed);
++			eth3220ac_release_bpf(port);
++			break;
++			
++		case WAIT_BYPASS_LINK_UP_POSITIVE:
++		case BYPASS_AND_LINK_UP_POSITIVE:
++			next_state = BYPASS_AND_LINK_UP_POSITIVE;
++			break;
++			
++		case WAIT_8101_LINK_UP_POSITIVE:
++			next_state = LINK_UP_8101_POSITIVE;
++			eth3220ac_link_agc(port, speed);
++			star_nic_write_phy(port, 12, 0x98ff);
++			break;
++			
++		case LINK_UP_8101_POSITIVE:
++			next_state = LINK_UP_8101_POSITIVE;
++			break;
++			
++		default:
++			next_state = LINK_UP_POSITIVE;
++			eth3220ac_def_linkup_setting(port);
++			eth3220ac_link_agc(port, speed);
++		}
++	} else {
++		/*  Link down state  */
++		switch(phy[port].state) {
++		case LINK_DOWN_POSITIVE:
++                        star_nic_read_phy(port, 5, &reg);	
++                        star_nic_read_phy(port, 28, &reg2);	
++			/* AN Link Partner Ability Register or NLP */
++			if (reg || (reg2 & 0x100))
++				next_state = WAIT_LINK_UP_POSITIVE;
++			else
++				next_state = LINK_DOWN_POSITIVE;
++			break;
++			
++		case WAIT_LINK_UP_POSITIVE:
++			if (phy[port].state_time > LINK_DOWN_ABILITY_DETECT_TIMEOUT)
++				next_state = LINK_DOWN_POSITIVE;
++			else
++				next_state = WAIT_LINK_UP_POSITIVE;
++			break;
++			
++		case WAIT_BYPASS_LINK_UP_POSITIVE:
++			/* set timeout = 5 sec */
++			if (phy[port].state_time > WAIT_BYPASS_LINK_UP_POSITIVE_TIMEOUT) {
++				next_state = LINK_DOWN_POSITIVE;
++				/* Bypass Filter disable */
++				eth3220ac_rt8100_linkdown(port);
++				eth3220ac_def_bpf(port);
++			} else {
++				next_state = WAIT_BYPASS_LINK_UP_POSITIVE;
++			}
++			break;
++			
++		case BYPASS_AND_LINK_UP_POSITIVE:
++			next_state = LINK_DOWN_POSITIVE;
++			eth3220ac_rt8100_linkdown(port);
++			eth3220ac_def_bpf(port);
++			break;
++			
++		case WAIT_8101_LINK_UP_POSITIVE:
++			if (phy[port].state_time > WAIT_8101_LINK_UP_TIMEOUT) {
++				next_state = LINK_DOWN_POSITIVE;
++				eth3220ac_normal_phy_setting(port);
++				eth3220ac_def_linkdown_setting(port);
++			} else {
++				next_state = WAIT_8101_LINK_UP_POSITIVE;
++			}
++			break;
++			
++		case LINK_UP_POSITIVE:
++			eth3220ac_unlink_agc(port);
++			eth3220ac_def_linkdown_setting(port);
++			eth3220ac_def_bpf(port);
++			if (phy[port].timer > DETECT_8101_PERIOD) {
++				next_state = LINK_DOWN_POSITIVE;
++				phy[port].timer = 0;
++				phy[port].linkdown_cnt = 1;
++			} else {
++				if (++phy[port].linkdown_cnt > 2) {
++					next_state = WAIT_8101_LINK_UP_POSITIVE;
++					eth3220ac_rt8101_phy_setting(port);
++				} else {
++					next_state = LINK_DOWN_POSITIVE;
++				}
++			}
++			break;
++			
++		case LINK_UP_8101_POSITIVE:
++			eth3220ac_normal_phy_setting(port);
++			/*  fall down to phy normal state  */
++		case PHY_STATE_INIT:
++			eth3220ac_def_linkdown_setting(port);
++			eth3220ac_unlink_agc(port);
++		default:
++			next_state = LINK_DOWN_POSITIVE;
++		}
++	}
++	
++	if (phy[port].state != next_state) {
++		phy[port].state_time = 0;
++#if DEBUG_PHY_STATE_TRANSITION
++		if (debug_phy_port == -1 || port == debug_phy_port)
++		{
++			if ((phy[port].state < PHY_STATE_LAST) && (next_state < PHY_STATE_LAST))
++			{
++				printk("p%d: %s->%s, %d, %d\n", port, phystate_name[phy[port].state],
++					phystate_name[next_state], phy[port].timer, phy[port].linkdown_cnt);
++			}
++			else
++			{
++				printk("p%d: %d->%d\n", port, phy[port].state, next_state);
++			}
++		}
++#endif   /*  DEBUG_PHY_STATE_TRANSITION  */
++	} else {
++		phy[port].state_time += ETH3220_PHY_MON_PERIOD;
++	}
++	phy[port].state = next_state;
++}
++
++/*=============================================================*
++ *  eth3220_phyinit:
++ *=============================================================*/
++static void eth3220ac_10m_agc(void)
++{
++	/* Force 10M AGC = 2c globally */
++	star_nic_write_phy(0, 31, 0x2f1a);
++	star_nic_write_phy(0, 12, 0x112c);
++	star_nic_write_phy(0, 13, 0x2e21);
++	star_nic_write_phy(0, 31, 0xaf1a);
++}
++
++static void eth3220ac_dfe_init(void)
++{
++	int i;
++
++	star_nic_write_phy(0, 31, 0x2f1a);
++	for (i=0; i <= 7; i++)
++		star_nic_write_phy(0, i, 0);
++	star_nic_write_phy(0, 11, 0x0b50);
++	star_nic_write_phy(0, 31, 0xaf1a);
++}
++
++static void eth3220ac_phy_cdr_training_init(void)
++{
++	int volatile i;
++
++	/* Force all port in 10M FD mode */
++	for (i=0; i < NUM_PHY; i++)
++		star_nic_write_phy(i, 0, 0x100);
++	
++	/* Global setting */
++	star_nic_write_phy(0, 31, 0x2f1a);
++	star_nic_write_phy(0, 29, 0x5021);
++        udelay(2000); //2ms, wait > 1 ms
++	star_nic_write_phy(0, 29, 0x4021);
++        udelay(2000); //2ms, wait > 1 ms
++	star_nic_write_phy(0, 31, 0xaf1a);
++
++	/* Enable phy AN */
++	for (i=0; i < NUM_PHY; i++)
++		star_nic_write_phy(i, 0, 0x3100);	
++}
++
++static void eth3220_phyinit(void)
++{
++	eth3220ac_10m_agc();
++	eth3220ac_dfe_init();
++	eth3220ac_phy_cdr_training_init();
++}
++
++static void eth3220_phycfg(int phyaddr)
++{
++	eth3220ac_def_linkdown_setting(phyaddr);
++	eth3220ac_normal_phy_setting(phyaddr);
++	star_nic_write_phy(phyaddr, 9, 0x7f);
++}
++
++static void internal_phy_patch_check(int init)
++{
++	u32 short_cable_agc_detect_count;
++	u32 link_status = 0, link_speed;
++	u32 ii, jj;
++	u16 phy_data;
++	u16 phy_data2;
++
++	star_nic_read_phy(STAR_NIC_PHY_ADDR, 1, &phy_data);
++	udelay(100);
++	star_nic_read_phy(STAR_NIC_PHY_ADDR, 1, &phy_data2);
++	if (((phy_data & 0x0004) != 0x0004) && ((phy_data2 & 0x0004) != 0x0004)) { // link down
++		short_cable_agc_detect_count = 0;
++		for (jj = 0; jj < INTERNAL_PHY_PATCH_CHECKCNT; jj++) {
++			star_nic_read_phy(STAR_NIC_PHY_ADDR, 15, &phy_data);
++			udelay(1000);
++			if (((phy_data) & 0x7F) <= 0x12) { // short cable
++				short_cable_agc_detect_count++;
++				break;
++			}
++		}
++		if (short_cable_agc_detect_count) { // short cable
++			phy_statemachine = wp3220ac_phystate;
++			eth3220_phyinit();
++			star_nic_read_phy(STAR_NIC_PHY_ADDR, 1, &phy_data);
++			if (phy_data & 0x0040) { // link up
++				link_status = 1;
++			}
++			if ((NIC_MAC_CONTROL_REG & 0xC) == 0x4) { // 100Mbps
++				link_speed = 1;
++			} else {
++				link_speed = 0;
++			}
++			link_status_old = link_status;
++			for (ii = 0; ii < MAX_PHY_PORT; link_status >>= 1, ii++) {
++				eth3220_phycfg(ii);
++#if 0
++				if (phy_statemachine != NULL)
++					(*phy_statemachine)(ii, link_status & 1, link_speed & 1);
++#endif
++			}
++		} else { // long cable
++			// set to global domain
++			star_nic_write_phy(NIC_PHY_ADDRESS, 31, 0x2f1a);
++			for (ii = 0; ii < 32; ii++) {
++				star_nic_write_phy(NIC_PHY_ADDRESS, ii, long_cable_global_reg[ii]);
++			}
++			// set to local domain
++			star_nic_write_phy(NIC_PHY_ADDRESS, 31, 0xaf1a);
++			for (ii = 0; ii < 32; ii++) {
++				star_nic_write_phy(NIC_PHY_ADDRESS, ii, long_cable_local_reg[ii]);
++			}
++		}
++	}
++}
++
++#endif
++//========================================================
+diff -rupN linux-2.6.35.11/drivers/net/str9100/dorado2.h linux-2.6.35.11-ts7500/drivers/net/str9100/dorado2.h
+--- linux-2.6.35.11/drivers/net/str9100/dorado2.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/dorado2.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,223 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef  DORADO2_H
++#define  DORADO2_H
++
++#include <linux/types.h>
++
++// this configure is for star dorado2
++
++// add by descent 2006/07/10
++#define DORADO2
++
++// add by KC 2006/09/07
++#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++// if no VSC8201 on MAC PORT1, we need to define this
++// if VSC8201 is present, mark it
++//#define DORADO2_PCI_FASTPATH_MAC_PORT1_LOOPBACK
++#endif
++
++#ifdef DORADO2
++// init phy or switch chip
++#define INIT_PORT0_PHY star_gsw_config_VSC7385();
++#ifdef DORADO2_PCI_FASTPATH_MAC_PORT1_LOOPBACK
++#define INIT_PORT1_PHY star_gsw_config_mac_port1_loopback();
++#else
++#define INIT_PORT1_PHY star_gsw_config_VSC8201(1,1);
++#endif
++//#define INIT_PORT1_PHY 
++
++// configure mac0/mac1 register
++#define INIT_PORT0_MAC init_packet_forward(0);
++#define INIT_PORT1_MAC init_packet_forward(1);
++//#define INIT_PORT1_MAC 
++
++#define PORT0_LINK_DOWN disable_AN(0, 0);
++#define PORT0_LINK_UP disable_AN(0, 1);
++
++#ifdef DORADO2_PCI_FASTPATH_MAC_PORT1_LOOPBACK
++#define PORT1_LINK_DOWN
++#define PORT1_LINK_UP
++#else
++#define PORT1_LINK_DOWN std_phy_power_down(1, 1);
++#define PORT1_LINK_UP std_phy_power_down(1, 0);
++#endif
++
++#define CREATE_NET_DEV0 star_gsw_probe(LAN_PORT);
++#define CREATE_NET_DEV1 star_gsw_probe(WAN_PORT);
++#define CREATE_NET_DEV2 star_gsw_probe(EWC_PORT);
++//#define CREATE_NET_DEV2 
++
++#define CONFIG_STR9100_PORT_BASE
++#define CONFIG_STR9100_VLAN_BASE
++//#define CONFIG_HAVE_VLAN_TAG
++
++// for port base, port base max is 2 port.
++// use in star_gsw_get_rfd_buff().
++// if a port no used, define to "0;"
++// NET_DEV0 : rx->sp 0 (port 0)
++#define NET_DEV0 0
++// NET_DEV1 : rx->sp 1 (port 1)
++#define NET_DEV1 STAR_GSW_EWC_DEV
++
++// for star_gsw_send_packet
++// port base and vlan base packet flow
++#define PORT_BASE_PMAP_LAN_PORT -1
++#define PORT_BASE_PMAP_WAN_PORT -1
++#define PORT_BASE_PMAP_EWC_PORT 2 // 2 port 1
++
++#define MODEL "DORADO2"
++
++// OPEN_PORT0 include 2 actions
++// 1. enable mac port
++// 2. link up port
++#define OPEN_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_EWC_DEV) { \
++		memcpy(dev->dev_addr, star_gsw_info.vlan[2].vlan_mac, 6);\
++		PRINT_INFO("open mac port1\n"); \
++		mac_port_config = GSW_MAC_PORT_1_CONFIG; \
++		/* disable port 1 */  \
++		mac_port_config &= (~(0x1 << 18)); \
++		GSW_MAC_PORT_1_CONFIG = mac_port_config; \
++		PORT1_LINK_UP \
++	} \
++	if (dev == STAR_GSW_LAN_DEV || dev == STAR_GSW_WAN_DEV) { \
++		if (dev == STAR_GSW_LAN_DEV) \
++			memcpy(dev->dev_addr, star_gsw_info.vlan[1].vlan_mac, 6);\
++		if (dev == STAR_GSW_WAN_DEV) \
++			memcpy(dev->dev_addr, star_gsw_info.vlan[0].vlan_mac, 6);\
++		/* rc_port is a reference count variable. */ \
++	        if (rc_port == 0) {\
++        		PRINT_INFO("open mac port 0\n");\
++		        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++               		/* enable port 0 */ \
++		        mac_port_config &= (~(0x1 << 18));\
++               		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++			PORT0_LINK_UP\
++	        }\
++	        else{\
++      			PRINT_INFO("port 0 already open\n");\
++	        }\
++		++rc_port;\
++	} \
++}
++
++// CLOSE_PORT include 2 actions
++// 1. disable mac port
++// 2. link down port
++#define CLOSE_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_EWC_DEV) { \
++		PRINT_INFO("close mac port1\n"); \
++		PORT1_LINK_DOWN \
++		mac_port_config = GSW_MAC_PORT_1_CONFIG; \
++		/* disable port 1 */  \
++		mac_port_config |= ((0x1 << 18)); \
++		GSW_MAC_PORT_1_CONFIG = mac_port_config; \
++	} \
++	if (dev == STAR_GSW_LAN_DEV || dev == STAR_GSW_WAN_DEV) { \
++		--rc_port;\
++		/* rc_port is a reference count variable. */ \
++	        if (rc_port == 0) {\
++        		PRINT_INFO("close mac port 0\n");\
++			PORT0_LINK_DOWN\
++		        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++               		/* disable port 0 */ \
++		        mac_port_config |= ((0x1 << 18));\
++               		 GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++	        }\
++	        else {\
++      			PRINT_INFO("a live net device\n");\
++	        }\
++	} \
++}
++
++
++
++#define VLAN0_VID			(0x2)
++#define VLAN1_VID			(0x1)
++#define VLAN2_VID			(0x3)
++#define VLAN3_VID			(0x4)
++#define VLAN4_VID			(0x5)
++#define VLAN5_VID			(0x6)
++#define VLAN6_VID			(0x7)
++#define VLAN7_VID			(0x8)
++
++#define VLAN0_GROUP			(PORT0 | CPU_PORT)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++#define VLAN2_GROUP			(PORT1 | CPU_PORT)
++#define VLAN3_GROUP			(PORT1 | CPU_PORT)
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#define VLAN7_GROUP			(PORT1 | CPU_PORT)
++
++
++#ifdef CONFIG_HAVE_VLAN_TAG
++
++#define VLAN0_VLAN_TAG			(5)	// cpu port and mac 0 port
++#define VLAN1_VLAN_TAG			(5)	// cpu port and mac 0 port
++
++#else
++#define VLAN0_VLAN_TAG			(1)	// only mac 0 port
++#define VLAN1_VLAN_TAG			(1)	// only mac 0 port
++#endif
++
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#define VLAN7_VLAN_TAG			(0)
++
++
++/* wan eth1 */
++static u8 my_vlan0_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x50};
++
++/* lan eth 0*/
++static u8 my_vlan1_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x60};
++
++/* cpu */
++static u8 my_vlan2_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x22};
++
++/* ewc  */
++static u8 my_vlan3_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x23};
++
++// this value is for hnat
++// GID is vlan group id
++#define LAN_GID 1
++#define WAN_GID 0
++
++
++#endif //DORADO2
++
++
++
++
++#endif
+diff -rupN linux-2.6.35.11/drivers/net/str9100/dorado.h linux-2.6.35.11-ts7500/drivers/net/str9100/dorado.h
+--- linux-2.6.35.11/drivers/net/str9100/dorado.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/dorado.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,188 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef  DORADO_H
++#define  DORADO_H
++
++int disable_AN(int port, int y);
++// this configure is for star dorado2
++
++// add by descent 2006/07/10
++#define DORADO
++#ifdef DORADO
++// init phy or switch chip
++#define INIT_PORT0_PHY star_gsw_config_VSC7385();
++#define INIT_PORT1_PHY 
++//#define INIT_PORT1_PHY 
++
++// configure mac0/mac1 register
++#define INIT_PORT0_MAC init_packet_forward(0);
++#define INIT_PORT1_MAC 
++//#define INIT_PORT1_MAC 
++
++#define PORT0_LINK_DOWN disable_AN(0, 0);
++#define PORT0_LINK_UP disable_AN(0, 1);
++
++#define PORT1_LINK_DOWN 
++#define PORT1_LINK_UP 
++
++#define CREATE_NET_DEV0 star_gsw_probe(LAN_PORT);
++#define CREATE_NET_DEV1 star_gsw_probe(WAN_PORT);
++#define CREATE_NET_DEV2 
++//#define CREATE_NET_DEV2 
++
++#undef CONFIG_STR9100_PORT_BASE
++#define CONFIG_STR9100_VLAN_BASE
++#undef CONFIG_HAVE_VLAN_TAG
++
++
++// for star_gsw_send_packet
++// port base and vlan base packet flow
++#define PORT_BASE_PMAP_LAN_PORT INVALID_PORT_BASE_PMAP_PORT
++#define PORT_BASE_PMAP_WAN_PORT INVALID_PORT_BASE_PMAP_PORT
++#define PORT_BASE_PMAP_EWC_PORT INVALID_PORT_BASE_PMAP_PORT
++
++#define MODEL "DORADO"
++
++// OPEN_PORT0 include 2 actions
++// 1. enable mac port
++// 2. link up port
++#define OPEN_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV || dev == STAR_GSW_WAN_DEV) { \
++		if (dev == STAR_GSW_LAN_DEV) { \
++			/*printk("STAR_GSW_LAN_DEV\n"); */ \
++			/*memcpy(dev->dev_addr, star_gsw_info.vlan[LAN_GID].vlan_mac, 6);*/ \
++		} \
++		if (dev == STAR_GSW_WAN_DEV) { \
++			/* printk("STAR_GSW_WAN_DEV\n"); */ \
++			/*memcpy(dev->dev_addr, star_gsw_info.vlan[WAN_GID].vlan_mac, 6);*/ \
++		} \
++		/* rc_port is a reference count variable. */ \
++	        if (rc_port == 0) {\
++        		PRINT_INFO("open mac port 0\n");\
++		        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++               		/* enable port 0 */ \
++		        mac_port_config &= (~(0x1 << 18));\
++               		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++			PORT0_LINK_UP\
++	        }\
++	        else{\
++      			PRINT_INFO("port 0 already open\n");\
++	        }\
++		++rc_port;\
++	} \
++}
++
++// CLOSE_PORT include 2 actions
++// 1. disable mac port
++// 2. link down port
++#define CLOSE_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV || dev == STAR_GSW_WAN_DEV) { \
++		/* rc_port is a reference count variable. */ \
++		--rc_port;\
++	        if (rc_port == 0) {\
++        		PRINT_INFO("close mac port 0\n");\
++			PORT0_LINK_DOWN\
++		        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++               		/* disable port 0 */ \
++		        mac_port_config |= ((0x1 << 18));\
++               		 GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++	        }\
++	        else {\
++      			PRINT_INFO("a live net device\n");\
++	        }\
++	} \
++}
++
++
++
++// the vlan past waht vlan tag value
++#define VLAN0_VID			(0x2) // wan
++#define VLAN1_VID			(0x1) // lan
++#define VLAN2_VID			(0x3)
++#define VLAN3_VID			(0x4)
++#define VLAN4_VID			(0x5)
++#define VLAN5_VID			(0x6)
++#define VLAN6_VID			(0x7)
++#define VLAN7_VID			(0x8)
++
++// the vlan include ports
++#define VLAN0_GROUP			(PORT0 | CPU_PORT)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++#define VLAN2_GROUP			(0)
++#define VLAN3_GROUP			(0)
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#define VLAN7_GROUP			(0)
++
++
++#ifdef CONFIG_HAVE_VLAN_TAG
++
++// the vlan which ports will past vlan tags.
++#define VLAN0_VLAN_TAG			(5)	// cpu port and mac 0 port
++#define VLAN1_VLAN_TAG			(5)	// cpu port and mac 0 port
++
++#else
++#define VLAN0_VLAN_TAG			(1)	// only mac 0 port
++#define VLAN1_VLAN_TAG			(1)	// only mac 0 port
++#endif
++
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#define VLAN7_VLAN_TAG			(0)
++
++
++/* wan eth1 */
++static u8 my_vlan0_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x50};
++
++/* lan eth 0*/
++static u8 my_vlan1_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x60};
++
++/* cpu */
++static u8 my_vlan2_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x22};
++
++/* ewc  */
++static u8 my_vlan3_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x23};
++
++// this value is for hnat
++// GID is vlan group id
++#define LAN_GID 1
++#define WAN_GID 0
++
++
++#endif //DORADO
++
++
++
++
++#endif
+diff -rupN linux-2.6.35.11/drivers/net/str9100/Kconfig linux-2.6.35.11-ts7500/drivers/net/str9100/Kconfig
+--- linux-2.6.35.11/drivers/net/str9100/Kconfig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,45 @@
++menu "CNS1100 Gigabit Switch support"
++	depends on ARCH_STR9100
++
++config STAR_GSW
++	tristate "CNS1100 Gigabit Switch driver support"
++
++config STR9100_SHNAT
++	bool "CNS1100 Smart HNAT Support"
++	depends on STAR_GSW
++	help
++	  Add STAR Smart HNAT support function in kernel
++
++config STAR9100_SHNAT_PCI_FASTPATH
++	bool "FastPath(From PCI to WAN) Support"
++	depends on STR9100_SHNAT
++	help
++	  Add FastPath Support for Smart HNAT.
++
++choice
++	prompt "CNS1100 Board"
++	depends on STAR_GSW
++	default DORADO
++
++config DORADO
++	bool "Dorado"
++
++config DORADO2
++	bool "Dorado2"
++
++config VIRGO
++	bool "Virgo"
++
++config VELA
++	bool "Vela"
++
++config LIBRA
++	bool "Libra"
++
++config LEO
++	bool "Leo"
++
++endchoice
++
++endmenu
++
+diff -rupN linux-2.6.35.11/drivers/net/str9100/leo.h linux-2.6.35.11-ts7500/drivers/net/str9100/leo.h
+--- linux-2.6.35.11/drivers/net/str9100/leo.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/leo.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,152 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef LEO_H
++#define LEO_H
++
++// add by descent 2006/07/10
++#define LEO
++#ifdef LEO
++// init phy or switch chip
++#define INIT_PORT0_PHY star_gsw_config_VSC8201(0,0);
++#define INIT_PORT1_PHY 
++
++// configure mac0/mac1 register
++#define INIT_PORT0_MAC init_packet_forward(0);
++#define INIT_PORT1_MAC disable_AN(1, 1);
++// if no disable_AN port 1, maybe get link up/down (change link state)
++
++#define PORT0_LINK_DOWN std_phy_power_down(0,1);
++#define PORT0_LINK_UP std_phy_power_down(0,0);
++
++#define PORT1_LINK_DOWN 
++#define PORT1_LINK_UP 
++
++#define CREATE_NET_DEV0 star_gsw_probe(LAN_PORT);
++#define CREATE_NET_DEV1 
++#define CREATE_NET_DEV2
++
++
++#define CONFIG_STR9100_PORT_BASE
++#undef CONFIG_STR9100_VLAN_BASE
++#undef CONFIG_HAVE_VLAN_TAG
++
++// for port base, port base max is 2 port.
++// NET_DEV0 : rx->sp 0 (port 0)
++#define NET_DEV0 STAR_GSW_LAN_DEV
++// NET_DEV1 : rx->sp 1 (port 1)
++#define NET_DEV1 0
++
++// for star_gsw_send_packet
++// port base and vlan base packet flow
++#define PORT_BASE_PMAP_LAN_PORT PORT0
++#define PORT_BASE_PMAP_WAN_PORT INVALID_PORT_BASE_PMAP_PORT
++#define PORT_BASE_PMAP_EWC_PORT INVALID_PORT_BASE_PMAP_PORT
++
++#define MODEL "LEO"
++
++// OPEN_PORT0 include 2 actions
++// 1. enable mac port
++// 2. link up port
++#define OPEN_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV) { \
++		memcpy(dev->dev_addr, star_gsw_info.vlan[1].vlan_mac, 6);\
++       		PRINT_INFO("open mac port 0\n");\
++	        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++       		/* enable port 0 */ \
++	        mac_port_config &= (~(0x1 << 18));\
++       		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++		PORT0_LINK_UP\
++	} \
++}
++
++// CLOSE_PORT include 2 actions
++// 1. disable mac port
++// 2. link down port
++#define CLOSE_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV) { \
++       		PRINT_INFO("close mac port 0\n");\
++		PORT0_LINK_DOWN\
++	        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++       		/* disable port 0 */ \
++	        mac_port_config |= ((0x1 << 18));\
++       		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++	} \
++}
++
++
++#define VLAN0_VID			(0x111)
++#define VLAN1_VID			(0x222)
++#define VLAN2_VID			(0x333)
++#define VLAN3_VID			(0x444)
++#define VLAN4_VID			(0x555)
++#define VLAN5_VID			(0x666)
++#define VLAN6_VID			(0x777)
++#define VLAN7_VID			(0x888)
++
++
++#define VLAN0_GROUP			(CPU_PORT | PORT0)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++//#define VLAN0_GROUP                     (PORT0 | PORT1 | CPU_PORT)
++//#define VLAN1_GROUP                     (PORT0 | CPU_PORT)
++//#define VLAN2_GROUP                     (PORT1 | CPU_PORT)
++#define VLAN2_GROUP			(0)
++#define VLAN3_GROUP			(0)
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#define VLAN7_GROUP			(0)
++
++#define VLAN0_VLAN_TAG			(0)
++#define VLAN1_VLAN_TAG			(0)
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#define VLAN7_VLAN_TAG			(0)
++
++//#define PORT0_PVID			(VLAN0_GROUP_ID)
++//#define PORT1_PVID			(VLAN2_GROUP_ID)
++//#define CPU_PORT_PVID			(VLAN1_GROUP_ID)
++
++static u8 my_vlan0_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x12};
++static u8 my_vlan1_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x22};
++static u8 my_vlan2_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x32};
++static u8 my_vlan3_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x42};
++
++// this value is for hnat
++// GID is vlan group id
++#define LAN_GID 0
++#define WAN_GID 2
++
++
++#endif // LEO
++
++#endif
+diff -rupN linux-2.6.35.11/drivers/net/str9100/libra.h linux-2.6.35.11-ts7500/drivers/net/str9100/libra.h
+--- linux-2.6.35.11/drivers/net/str9100/libra.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/libra.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,184 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef  LIBRA_H
++#define  LIBRA_H
++
++// this configure is for star LIBRA
++
++// add by descent 2006/07/10
++#define LIBRA
++#ifdef LIBRA
++// init phy or switch chip
++#define INIT_PORT0_PHY configure_icplus_175c_phy();
++#define INIT_PORT1_PHY 
++//#define INIT_PORT1_PHY 
++
++// configure mac0/mac1 register
++#define INIT_PORT0_MAC init_packet_forward(0);
++#define INIT_PORT1_MAC 
++//#define INIT_PORT1_MAC 
++
++#define PORT0_LINK_DOWN icp_175c_all_phy_power_down(1);
++#define PORT0_LINK_UP icp_175c_all_phy_power_down(0);
++
++#define PORT1_LINK_DOWN 
++#define PORT1_LINK_UP 
++
++#define CREATE_NET_DEV0 star_gsw_probe(LAN_PORT);
++#define CREATE_NET_DEV1 star_gsw_probe(WAN_PORT);
++#define CREATE_NET_DEV2 
++//#define CREATE_NET_DEV2 
++
++#undef CONFIG_STR9100_PORT_BASE
++#define CONFIG_STR9100_VLAN_BASE
++#undef CONFIG_HAVE_VLAN_TAG
++#define CONFIG_HAVE_VLAN_TAG
++
++
++// for star_gsw_send_packet
++// port base and vlan base packet flow
++#define PORT_BASE_PMAP_LAN_PORT INVALID_PORT_BASE_PMAP_PORT
++#define PORT_BASE_PMAP_WAN_PORT INVALID_PORT_BASE_PMAP_PORT
++#define PORT_BASE_PMAP_EWC_PORT INVALID_PORT_BASE_PMAP_PORT
++
++#define MODEL "LIBRA"
++
++// OPEN_PORT0 include 2 actions
++// 1. enable mac port
++// 2. link up port
++#define OPEN_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV || dev == STAR_GSW_WAN_DEV) { \
++		if (dev == STAR_GSW_LAN_DEV) \
++			memcpy(dev->dev_addr, star_gsw_info.vlan[LAN_GID].vlan_mac, 6);\
++		if (dev == STAR_GSW_WAN_DEV) \
++			memcpy(dev->dev_addr, star_gsw_info.vlan[WAN_GID].vlan_mac, 6);\
++		/* rc_port is a reference count variable. */ \
++	        if (rc_port == 0) {\
++        		PRINT_INFO("open mac port 0\n");\
++		        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++               		/* enable port 0 */ \
++		        mac_port_config &= (~(0x1 << 18));\
++               		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++			PORT0_LINK_UP\
++	        }\
++	        else{\
++      			PRINT_INFO("port 0 already open\n");\
++	        }\
++		++rc_port;\
++	} \
++}
++
++// CLOSE_PORT include 2 actions
++// 1. disable mac port
++// 2. link down port
++#define CLOSE_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV || dev == STAR_GSW_WAN_DEV) { \
++		/* rc_port is a reference count variable. */ \
++		--rc_port;\
++	        if (rc_port == 0) {\
++        		PRINT_INFO("close mac port 0\n");\
++			PORT0_LINK_DOWN\
++		        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++               		/* disable port 0 */ \
++		        mac_port_config |= ((0x1 << 18));\
++               		 GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++	        }\
++	        else {\
++      			PRINT_INFO("a live net device\n");\
++	        }\
++	} \
++}
++
++
++
++// the vlan past waht vlan tag value
++#define VLAN0_VID			(0x2) // wan
++#define VLAN1_VID			(0x1) // lan
++#define VLAN2_VID			(0x3)
++#define VLAN3_VID			(0x4)
++#define VLAN4_VID			(0x5)
++#define VLAN5_VID			(0x6)
++#define VLAN6_VID			(0x7)
++#define VLAN7_VID			(0x8)
++
++// the vlan include ports
++#define VLAN0_GROUP			(PORT0 | CPU_PORT)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++#define VLAN2_GROUP			(0)
++#define VLAN3_GROUP			(0)
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#define VLAN7_GROUP			(0)
++
++
++#ifdef CONFIG_HAVE_VLAN_TAG
++
++// the vlan which ports will past vlan tags.
++#define VLAN0_VLAN_TAG			(5)	// cpu port and mac 0 port
++#define VLAN1_VLAN_TAG			(5)	// cpu port and mac 0 port
++
++#else
++#define VLAN0_VLAN_TAG			(1)	// only mac 0 port
++#define VLAN1_VLAN_TAG			(1)	// only mac 0 port
++#endif
++
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#define VLAN7_VLAN_TAG			(0)
++
++
++/* wan eth1 */
++static u8 my_vlan0_mac[6] = {0x00, 0x11, 0xbb, 0xcc, 0xdd, 0x50};
++
++/* lan eth 0*/
++static u8 my_vlan1_mac[6] = {0x00, 0x11, 0xbb, 0xcc, 0xdd, 0x60};
++
++/* cpu */
++static u8 my_vlan2_mac[6] = {0x00, 0x11, 0xbb, 0xcc, 0xdd, 0x22};
++
++/* ewc  */
++static u8 my_vlan3_mac[6] = {0x00, 0x11, 0xbb, 0xcc, 0xdd, 0x23};
++
++// this value is for hnat
++// GID is vlan group id
++#define LAN_GID 1
++#define WAN_GID 0
++
++
++#endif //LIBRA
++
++
++
++
++#endif
+diff -rupN linux-2.6.35.11/drivers/net/str9100/Makefile linux-2.6.35.11-ts7500/drivers/net/str9100/Makefile
+--- linux-2.6.35.11/drivers/net/str9100/Makefile	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,38 @@
++################################################################################
++#
++# 
++# Copyright(c) 2005 -  Star semiconduction. All rights reserved.
++# 
++# This program is free software; you can redistribute it and/or modify it 
++# under the terms of the GNU General Public License as published by the Free 
++# Software Foundation; either version 2 of the License, or (at your option) 
++# any later version.
++# 
++# This program is distributed in the hope that it will be useful, but WITHOUT 
++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
++# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
++# more details.
++# 
++# You should have received a copy of the GNU General Public License along with
++# this program; if not, write to the Free Software Foundation, Inc., 59 
++# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++# 
++# The full GNU General Public License is included in this distribution in the
++# file called LICENSE.
++# 
++# Contact Information:
++# Star semiconduction Linux Support <support at 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 at starsemi.com>");
++MODULE_DESCRIPTION("Star Switch Driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(DRV_VERSION);
++
++
++
++module_init(star_gsw_init_module);
++module_exit(star_gsw_exit_module);
++
+diff -rupN linux-2.6.35.11/drivers/net/str9100/star_gsw_config.h linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw_config.h
+--- linux-2.6.35.11/drivers/net/str9100/star_gsw_config.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw_config.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,288 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __STAR_GSW_CONFIG_H__
++#define __STAR_GSW_CONFIG_H__
++
++
++// add by descent 2006/07/05
++// this debug macro reference linux device drivers, 2e
++
++
++// 20060922 descent
++// in dorado, if NIC mode on, and use ARL search, need enable STR9100_GSW_FAST_AGE_OUT
++// NIC mode is experiment, don't recommand use it.
++#define CONFIG_NIC_MODE
++
++// 20060922 descent end
++
++//#define STR9100_GSW_DEBUG
++
++
++#ifdef SHOW_DEBUG_MESSAGE
++
++#define NORMAL_MSG 1
++#define WARNING_MSG (1 << 1)
++#define CRITICAL_MSG (1 << 2)
++
++#define DEBUG_MSG(msg_level, fmt, args...)\
++{ \
++        int i=0; \
++\
++        for(i=0 ; i < 3 ; ++i) { \
++                if ((MSG_LEVEL & msg_level) >> i) \
++                        printk (KERN_INFO "*str9100_gsw_debug* " fmt, ## args); \
++        } \
++}
++
++#endif
++
++
++
++// direction is "TX" or "RX"
++#define PRINT_PACKET(data, len, direction) \
++{ \
++	printk(direction); \
++	print_packet(data, len); \
++}
++
++#undef PDEBUG
++  #ifdef STR9100_GSW_DEBUG
++    #ifdef __KERNEL__
++      #define PDEBUG(fmt, args...) printk (KERN_INFO "*str9100_gsw_debug* " fmt, ## args)
++      //#define PDEBUG printk 
++    #else
++      #define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
++    #endif // __KERNEL__
++  #else
++    #define PDEBUG(fmt, args...)
++  #endif
++
++#undef PDEBUGG
++#define PDEBUGG(fmt, args...)
++
++// 20061103 descent
++//#define CONFIG_CONF_VID
++// 20061103 descent end
++
++
++// modify by descent 2006/07/05
++// use for print needed message
++#if 1
++#define PRINT_INFO printk 
++#else
++#define PRINT_INFO(arg...)
++#endif
++
++
++#define CONFIG_STAR_GSW_NAPI
++
++// add by descent 2006/07/07
++// in star_gsw_get_rfd_buff
++// if define CONFIG_STAR_GSW_BRIDGE drop no packets
++// else drop invalid packets.
++
++
++#include <linux/config.h>
++#ifdef CONFIG_BRIDGE // reference linux config network bridge
++#define CONFIG_STAR_GSW_BRIDGE
++#endif
++
++// add by descent 2006/07/05
++// 1 mean rate controll on
++// 0 mean rate controll off
++#define STR9100_GSW_BROADCAST_RATE_CONTROL 0
++#define STR9100_GSW_MULTICAST_RATE_CONTROL 0
++#define STR9100_GSW_UNKNOW_PACKET_RATE_CONTROL 0
++
++// 1 mean forwarding off
++// 0 mean forwarding on
++#define STR9100_GSW_DISABLE_FORWARDING_BROADCAST_PACKET 0
++#define STR9100_GSW_DISABLE_FORWARDING_MULTICAST_PACKET 0
++#define STR9100_GSW_DISABLE_FORWARDING_UNKNOW_PACKET 0
++
++//#define STR9100_GSW_FAST_AGE_OUT
++
++#define STAR_GSW_TX_HW_CHECKSUM
++#define STAR_GSW_RX_HW_CHECKSUM
++
++
++//#define STAR_GSW_TIMER
++//#define FREE_TX_SKB_MULTI
++#define STAR_GSW_SG
++#if defined(STAR_GSW_SG) && !defined(STAR_GSW_TX_HW_CHECKSUM)
++#define STAR_GSW_TX_HW_CHECKSUM
++#endif
++
++
++//#define ADJUSTMENT_TX_RX_SKEW
++//#define STAR_GSW_STATUS_ISR
++#define STAR_GSW_FSQF_ISR
++
++
++// adjust MAX_PEND_INT_CNT and MAX_PEND_TIME at run time.
++//#define CHANGE_DELAY_INT
++
++#define STAR_GSW_DELAYED_INTERRUPT
++
++#define MAX_PEND_INT_CNT	0x06
++#define MAX_PEND_TIME		0x20
++
++/*
++ * This tag is for 9102 + 9109 Case only, and 9102's MAC0 Connect ot 9102's MAC1
++ */
++#ifdef CONFIG_STAR_GSW_TYPE_EWC
++#define CONFIG_STAR_GSW_TYPE_ONEARM "y"
++#undef CONFIG_SERCOMM_VSC7385
++#endif
++
++#if 0
++
++#define VLAN0_GROUP_ID			(0)
++#define VLAN1_GROUP_ID			(1)
++#define VLAN2_GROUP_ID			(2)
++#define VLAN3_GROUP_ID			(3)
++#define VLAN4_GROUP_ID			(4)
++#define VLAN5_GROUP_ID			(5)
++#define VLAN6_GROUP_ID			(6)
++#define VLAN7_GROUP_ID			(7)
++
++
++
++
++
++#ifdef CONFIG_STAR_GSW_TYPE_ONEARM
++#ifdef CONFIG_SERCOMM_VSC7385
++#define VLAN0_VID			(0x1)
++#define VLAN1_VID			(0x2)
++#define VLAN2_VID			(0x3)
++#define VLAN3_VID			(0x4)
++#define VLAN4_VID			(0x5)
++#define VLAN5_VID			(0x6)
++#define VLAN6_VID			(0x7)
++#define VLAN7_VID			(0x8)
++#else
++#define VLAN0_VID			(0x2)
++#define VLAN1_VID			(0x1)
++#define VLAN2_VID			(0x3)
++#define VLAN3_VID			(0x4)
++#define VLAN4_VID			(0x5)
++#define VLAN5_VID			(0x6)
++#define VLAN6_VID			(0x7)
++#define VLAN7_VID			(0x8)
++#endif
++#else
++#define VLAN0_VID			(0x111)
++#define VLAN1_VID			(0x222)
++#define VLAN2_VID			(0x333)
++#define VLAN3_VID			(0x444)
++#define VLAN4_VID			(0x555)
++#define VLAN5_VID			(0x666)
++#define VLAN6_VID			(0x777)
++#define VLAN7_VID			(0x888)
++#endif
++
++#define PORT0				(1 << 0)	/* bit map : bit 0 */
++#define PORT1				(1 << 1)	/* bit map : bit 1 */
++#define CPU_PORT			(1 << 2)	/* bit map : bit 2 */
++
++#ifdef CONFIG_STAR_GSW_TYPE_ONEARM
++#define VLAN0_GROUP			(PORT0 | CPU_PORT)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++#ifdef CONFIG_STAR_GSW_TYPE_EWC
++#define VLAN2_GROUP			(PORT1 | CPU_PORT)
++#define VLAN3_GROUP			(PORT1 | CPU_PORT)
++#else
++#define VLAN2_GROUP			(0)
++#define VLAN3_GROUP			(0)
++#endif
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#ifdef CONFIG_STAR_GSW_TYPE_EWC
++#define VLAN7_GROUP			(PORT1 | CPU_PORT)
++#else
++#define VLAN7_GROUP			(0)
++#endif
++
++#else
++#define VLAN0_GROUP			(PORT0 | PORT1 | CPU_PORT)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++#define VLAN2_GROUP			(PORT1 | CPU_PORT)
++#define VLAN3_GROUP			(0)
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#define VLAN7_GROUP			(0)
++#endif
++
++#ifdef CONFIG_STAR_GSW_TYPE_ONEARM
++
++#ifdef CONFIG_HAVE_VLAN_TAG
++
++#define VLAN0_VLAN_TAG			(5)	// cpu port and mac 0 port
++#define VLAN1_VLAN_TAG			(5)	// cpu port and mac 0 port
++
++#else
++#define VLAN0_VLAN_TAG			(1)	// only mac 0 port
++#define VLAN1_VLAN_TAG			(1)	// only mac 0 port
++#endif
++
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#ifdef CONFIG_STAR_GSW_TYPE_EWC
++#define VLAN7_VLAN_TAG			(0)	// MAC1 don't need Tag
++#else
++#define VLAN7_VLAN_TAG			(0)
++#endif
++#else
++#define VLAN0_VLAN_TAG			(0)
++#define VLAN1_VLAN_TAG			(0)
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#define VLAN7_VLAN_TAG			(0)
++#endif
++
++
++#define PORT0_PVID			(VLAN1_GROUP_ID)
++#define PORT1_PVID			(VLAN2_GROUP_ID)
++#define CPU_PORT_PVID			(VLAN0_GROUP_ID)
++
++#endif
++
++#define MAX_PACKET_LEN			(1536)
++
++/* 
++ * Maximum Transmit/Receive Frame Descriptors for GSW's MAC frame
++ * the value of tx/rx set to 40/48 is suggested.
++ */
++#define STAR_GSW_MAX_TFD_NUM		40
++#define STAR_GSW_MAX_RFD_NUM		48
++
++#endif /* __STAR_GSW_CONFIG_H__ */
+diff -rupN linux-2.6.35.11/drivers/net/str9100/star_gsw.h linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw.h
+--- linux-2.6.35.11/drivers/net/str9100/star_gsw.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,682 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef STAR_GSW_H
++#define STAR_GSW_H
++
++#include "star_gsw_phy.h"
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/bootmem.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/fcntl.h>
++#include <linux/interrupt.h>
++#include <linux/ptrace.h>
++#include <linux/ioport.h>
++#include <linux/in.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++#include <linux/reboot.h>
++#include <asm/bitops.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <asm/hardware.h>
++#include <linux/pci.h>
++#include <linux/errno.h>
++#include <linux/delay.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/ip.h>
++#include <linux/if_ether.h>
++#include <linux/icmp.h>
++#include <linux/udp.h>
++#include <linux/tcp.h>
++#include <linux/if_arp.h>
++#include <net/arp.h>
++
++#if defined(LINUX24)
++#include <asm/arch/str9100/star_gsw.h>
++#include <asm/arch/str9100/star_gpio.h>
++#include <asm/arch/str9100/star_powermgt.h>
++#endif
++
++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++#include <linux/if_vlan.h>
++#endif
++
++
++
++
++#include "star_gsw_config.h"
++
++#ifndef BIT
++#define BIT(x)		((1 << (x)))
++#endif
++
++#define LAN_PORT	1
++#define WAN_PORT	2
++#define EWC_PORT	3
++#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++
++#define TUN_PORT	4
++#define PMAP_TUN_PORT	8
++#define CREATE_NET_DEV_AD star_gsw_probe_tun();
++#define PORT_BASE_PMAP_TUN_PORT	PMAP_TUN_PORT
++#else
++#define CREATE_NET_DEV_AD
++#define PORT_BASE_PMAP_TUN_PORT
++#endif
++
++
++// add by descent 2006/07/10
++#define PMAP_PORT0	1
++#define PMAP_PORT1	2
++#define PMAP_CPU_PORT	4
++
++
++/*
++ * macro declarations
++ */
++#define GSW_SET_PORT0_PVID(port0_pvid) \
++{ \
++	((GSW_VLAN_PORT_PVID) &= (~(0x7 << 0))); \
++	((GSW_VLAN_PORT_PVID) |= ((port0_pvid) & 0x07)); \
++}
++
++#define GSW_SET_PORT1_PVID(port1_pvid) \
++{ \
++	((GSW_VLAN_PORT_PVID) &= (~(0x7 << 4))); \
++	((GSW_VLAN_PORT_PVID) |= (((port1_pvid) & 0x07) << 4)); \
++}
++
++#define GSW_SET_CPU_PORT_PVID(cpu_port_pvid) \
++{ \
++	((GSW_VLAN_PORT_PVID) &= (~(0x7 << 8))); \
++	((GSW_VLAN_PORT_PVID) |= (((cpu_port_pvid) & 0x07) << 8)); \
++}
++
++#define GSW_SET_VLAN_0_VID(vid) \
++{ \
++	((GSW_VLAN_VID_0_1) &= (~(0xFFF << 0))); \
++	((GSW_VLAN_VID_0_1) |= (((vid) & 0xFFF) << 0)); \
++}
++
++#define GSW_SET_VLAN_1_VID(vid) \
++{ \
++	((GSW_VLAN_VID_0_1) &= (~(0xFFF << 12))); \
++	((GSW_VLAN_VID_0_1) |= (((vid) & 0xFFF) << 12)); \
++}
++
++#define GSW_SET_VLAN_2_VID(vid) \
++{ \
++	((GSW_VLAN_VID_2_3) &= (~(0xFFF << 0))); \
++	((GSW_VLAN_VID_2_3) |= (((vid) & 0xFFF) << 0)); \
++}
++
++#define GSW_SET_VLAN_3_VID(vid) \
++{ \
++	((GSW_VLAN_VID_2_3) &= (~(0xFFF << 12))); \
++	((GSW_VLAN_VID_2_3) |= (((vid) & 0xFFF) << 12)); \
++}
++
++#define GSW_SET_VLAN_4_VID(vid) \
++{ \
++	((GSW_VLAN_VID_4_5) &= (~(0xFFF << 0))); \
++	((GSW_VLAN_VID_4_5) |= (((vid) & 0xFFF) << 0)); \
++}
++
++#define GSW_SET_VLAN_5_VID(vid) \
++{ \
++	((GSW_VLAN_VID_4_5) &= (~(0xFFF << 12))); \
++	((GSW_VLAN_VID_4_5) |= (((vid) & 0xFFF) << 12)); \
++}
++
++#define GSW_SET_VLAN_6_VID(vid) \
++{ \
++	((GSW_VLAN_VID_6_7) &= (~(0xFFF << 0))); \
++	((GSW_VLAN_VID_6_7) |= (((vid) & 0xFFF) << 0)); \
++}
++
++#define GSW_SET_VLAN_7_VID(vid) \
++{ \
++	((GSW_VLAN_VID_6_7) &= (~(0xFFF << 12))); \
++	((GSW_VLAN_VID_6_7) |= (((vid) & 0xFFF) << 12)); \
++}
++
++#define GSW_SET_VLAN_0_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 0))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 0)); \
++}
++
++#define GSW_SET_VLAN_1_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 3))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 3)); \
++}
++
++#define GSW_SET_VLAN_2_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 6))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 6)); \
++}
++
++#define GSW_SET_VLAN_3_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 9))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 9)); \
++}
++
++#define GSW_SET_VLAN_4_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 12))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 12)); \
++}
++
++#define GSW_SET_VLAN_5_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 15))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 15)); \
++}
++
++#define GSW_SET_VLAN_6_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 18))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 18)); \
++}
++
++#define GSW_SET_VLAN_7_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 21))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 21)); \
++}
++
++#define GSW_SET_VLAN_0_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 0))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 0)); \
++}
++
++#define GSW_SET_VLAN_1_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 3))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 3)); \
++}
++
++#define GSW_SET_VLAN_2_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 6))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 6)); \
++}
++
++#define GSW_SET_VLAN_3_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 9))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 9)); \
++}
++
++#define GSW_SET_VLAN_4_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 12))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 12)); \
++}
++
++#define GSW_SET_VLAN_5_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 15))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 15)); \
++}
++
++#define GSW_SET_VLAN_6_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 18))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 18)); \
++}
++
++#define GSW_SET_VLAN_7_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 21))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 21)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_0_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_0_1) &= (~(0xFFFF << 0))); \
++	((GSW_PPPOE_SESSION_ID_0_1) |= (((session_id) & 0xFFFF) << 0)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_1_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_0_1) &= (~(0xFFFF << 16))); \
++	((GSW_PPPOE_SESSION_ID_0_1) |= (((session_id) & 0xFFFF) << 16)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_2_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_2_3) &= (~(0xFFFF << 0))); \
++	((GSW_PPPOE_SESSION_ID_2_3) |= (((session_id) & 0xFFFF) << 0)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_3_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_2_3) &= (~(0xFFFF << 16))); \
++	((GSW_PPPOE_SESSION_ID_2_3) |= (((session_id) & 0xFFFF) << 16)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_4_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_4_5) &= (~(0xFFFF << 0))); \
++	((GSW_PPPOE_SESSION_ID_4_5) |= (((session_id) & 0xFFFF) << 0)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_5_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_4_5) &= (~(0xFFFF << 16))); \
++	((GSW_PPPOE_SESSION_ID_4_5) |= (((session_id) & 0xFFFF) << 16)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_6_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_6_7) &= (~(0xFFFF << 0))); \
++	((GSW_PPPOE_SESSION_ID_6_7) |= (((session_id) & 0xFFFF) << 0)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_7_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_6_7) &= (~(0xFFFF << 16))); \
++	((GSW_PPPOE_SESSION_ID_6_7) |= (((session_id) & 0xFFFF) << 16)); \
++}
++
++#define GSW_READ_INTERRUPT_STATUS(int_status) \
++	((int_status) = (GSW_INTERRUPT_STATUS))
++
++#define GSW_CLEAR_ALL_INTERRUPT_STATUS_SOURCES()\
++	((GSW_INTERRUPT_STATUS) = (0x00001FFF))
++
++#define GSW_CLEAR_INTERRUPT_STATUS_SOURCES(source) \
++	((GSW_INTERRUPT_STATUS) |= (source))
++
++#define GSW_CLEAR_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++	((GSW_INTERRUPT_STATUS) |= (1 << (source_bit_index)))
++
++#define GSW_DISABLE_ALL_INTERRUPT_STATUS_SOURCES() \
++	((GSW_INTERRUPT_MASK) = (0x00001FFF))
++
++#define GSW_ENABLE_ALL_INTERRUPT_STATUS_SOURCES() \
++	((GSW_INTERRUPT_MASK) = (0x00000000))
++
++#define GSW_DISABLE_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++	((GSW_INTERRUPT_MASK) |= (1 << (source_bit_index)))
++
++#define GSW_ENABLE_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++	((GSW_INTERRUPT_MASK) &= ~(1 << (source_bit_index)))
++
++#define GSW_TS_DMA_START() \
++	((GSW_TS_DMA_CONTROL) = (1))
++
++#define GSW_TS_DMA_STOP() \
++	((GSW_TS_DMA_CONTROL) = (0))
++
++#define GSW_READ_TS_DMA_STATE(state) \
++	((state) = (GSW_TS_DMA_CONTROL))
++
++#define GSW_FS_DMA_START() \
++	((GSW_FS_DMA_CONTROL) = (1))
++
++#define GSW_FS_DMA_STOP() \
++	((GSW_FS_DMA_CONTROL) = (0))
++
++#define GSW_WRITE_TSSD(tssd_value) \
++	((GSW_TS_DESCRIPTOR_POINTER) = (tssd_value))
++
++#define GSW_READ_TSSD(tssd_value) \
++	((tssd_value) = (GSW_TS_DESCRIPTOR_POINTER))
++
++#define GSW_WRITE_FSSD(fssd_value) \
++	((GSW_FS_DESCRIPTOR_POINTER) = (fssd_value))
++
++#define GSW_READ_FSSD(fssd_value) \
++	((fssd_value) = (GSW_FS_DESCRIPTOR_POINTER))
++
++#define GSW_WRITE_TS_BASE(ts_base_value) \
++	((GSW_TS_DESCRIPTOR_BASE_ADDR) = (ts_base_value))
++
++#define GSW_READ_TS_BASE(ts_base_value) \
++	((ts_base_value) = (GSW_TS_DESCRIPTOR_BASE_ADDR))
++
++#define GSW_WRITE_FS_BASE(fs_base_value) \
++	((GSW_FS_DESCRIPTOR_BASE_ADDR) = (fs_base_value))
++
++#define GSW_READ_FS_BASE(fs_base_value) \
++	((fs_base_value) = (GSW_FS_DESCRIPTOR_BASE_ADDR))
++
++/*
++ * HNAT macros defines
++ */
++#define GSW_WRITE_HNAT_CONFIGURATION(hnat_config) \
++	((GSW_HNAT_CONFIG) = (hnat_config))
++
++#define GSW_READ_HNAT_CONFIGURATION(hnat_config) \
++	((hnat_config) = (GSW_HNAT_CONFIG))
++
++#define GSW_WRITE_PRIVATE_IP_BASE(ip_base) \
++	((GSW_HNAT_PRIVATE_IP_BASE) = (ip_base & 0x000FFFFF))
++
++#define GSW_WRITE_HNAT_FW_RULE_START_INDEX(rule_start_index) \
++	((GSW_HNAT_FW_RULE_START_ADDR) = (rule_start_index & 0x1FF))
++
++#define GSW_WRITE_HNAT_FW_RULE_END_INDEX(rule_end_index) \
++	((GSW_HNAT_FW_RULE_END_ADDR) = (rule_end_index & 0x1FF))
++
++#define GSW_READ_HNAT_FW_RULE_START_INDEX(rule_start_index) \
++	((rule_start_index) = ((GSW_HNAT_FW_RULE_START_ADDR) & 0x1FF))
++
++#define GSW_READ_HNAT_FW_RULE_END_INDEX(rule_end_index) \
++	((rule_end_index) = ((GSW_HNAT_FW_RULE_END_ADDR) & 0x1FF))
++
++#define GSW_WRITE_HNAT_FL_RULE_START_INDEX(rule_start_index) \
++	((GSW_HNAT_FL_RULE_START_ADDR) = (rule_start_index & 0x1FF))
++
++#define GSW_WRITE_HNAT_FL_RULE_END_INDEX(rule_end_index) \
++	((GSW_HNAT_FL_RULE_END_ADDR) = (rule_end_index & 0x1FF))
++
++#define GSW_READ_HNAT_FL_RULE_START_INDEX(rule_start_index) \
++	((rule_start_index) = ((GSW_HNAT_FL_RULE_START_ADDR) & 0x1FF))
++
++#define GSW_READ_HNAT_FL_RULE_END_INDEX(rule_end_index) \
++	((rule_end_index) = ((GSW_HNAT_FL_RULE_END_ADDR) & 0x1FF))
++
++#define GSW_WRITE_HNAT_ALG_START_INDEX(rule_start_index) \
++	((GSW_HNAT_ALG_START_ADDR) = (rule_start_index & 0x1FF))
++
++#define GSW_WRITE_HNAT_ALG_END_INDEX(rule_end_index) \
++	((GSW_HNAT_ALG_END_ADDR) = (rule_end_index & 0x1FF))
++
++#define GSW_READ_HNAT_ALG_START_INDEX(rule_start_index) \
++	((rule_start_index) = ((GSW_HNAT_ALG_START_ADDR) & 0x1FF))
++
++#define GSW_READ_HNAT_ALG_END_INDEX(rule_end_index) \
++	((rule_end_index) = ((GSW_HNAT_ALG_END_ADDR) & 0x1FF))
++
++#define GSW_WRITE_HNAT_SIP_START_INDEX(rule_start_index) \
++	((GSW_HNAT_SIP_BASE_ADDR) = (rule_start_index & 0x1FF))
++
++#define GSW_READ_HNAT_SIP_START_INDEX(rule_start_index) \
++	((rule_start_index) = ((GSW_HNAT_SIP_BASE_ADDR) & 0x1FF))
++
++#define GSW_WRITE_HNAT_NAPT_BASE_ADDR(base_addr) \
++	((GSW_HNAT_NAPT_BASE_ADDR) = (base_addr))
++
++#define GSW_READ_HNAT_NAPT_BASE_ADDR(base_addr) \
++	((base_addr) = (GSW_HNAT_NAPT_BASE_ADDR))
++
++#define GSW_WRITE_HNAT_NAPT_PORT_BASE(port_base) \
++	((GSW_HNAT_NAPT_PORT_BASE) = (port_base & 0xFFFF))
++
++#define GSW_WRITE_HNAT_ARP_BASE_ADDR(base_addr) \
++	((GSW_HNAT_ARP_BASE_ADDR) = (base_addr))
++
++#define GSW_READ_HNAT_ARP_BASE_ADDR(base_addr) \
++	((base_addr) = (GSW_HNAT_ARP_BASE_ADDR))
++
++//---------------------------------------------------
++//      STAR9100   INTC  macro define
++//---------------------------------------------------
++/*
++ * macro declarations
++ */
++#define INTC_ENABLE_INTERRUPT_SOURCE(source_bit_index) \
++	(INTC_INTERRUPT_MASK) &= (~(1 << source_bit_index))
++
++#define INTC_DISABLE_INTERRUPT_SOURCE(source_bit_index) \
++	(INTC_INTERRUPT_MASK) |= ((1 << source_bit_index))
++
++#define INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(source_bit_index) \
++	(INTC_INTERRUPT_CLEAR_EDGE_TRIGGER) |= ((1 << source_bit_index))
++
++#define INTC_SET_INTERRUPT_EDGE_TRIGGER(source_bit_index) \
++	(INTC_INTERRUPT_TRIGGER_MODE) |= ((1 << source_bit_index))
++
++#define INTC_SET_INTERRUPT_LEVEL_TRIGGER(source_bit_index) \
++	(INTC_INTERRUPT_TRIGGER_MODE) &= (~(1 << source_bit_index))
++
++#define INTC_SET_INTERRUPT_RISING_EDGE_TRIGGER(source_bit_index) \
++	(INTC_INTERRUPT_TRIGGER_LEVEL) &= (~(1 << source_bit_index))
++
++#define INTC_SET_INTERRUPT_FALLING_EDGE_TRIGGER(source_bit_index) \
++	(INTC_INTERRUPT_TRIGGER_LEVEL) |= ((1 << source_bit_index))
++
++#define INTC_SET_INTERRUPT_ACTIVE_HIGH_LEVEL_TRIGGER(source_bit_index) \
++	(INTC_INTERRUPT_TRIGGER_LEVEL) &= (~(1 << source_bit_index))
++
++#define INTC_SET_INTERRUPT_ACTIVE_LOW_LEVEL_TRIGGER(source_bit_index) \
++	(INTC_INTERRUPT_TRIGGER_LEVEL) |= ((1 << source_bit_index))
++
++#define INTC_ASSIGN_INTERRUPT_TO_IRQ(source_bit_index) \
++	(INTC_FIQ_MODE_SELECT) &= (~(1 << source_bit_index))
++
++#define INTC_ASSIGN_INTERRUPT_TO_FIQ(source_bit_index) \
++	(INTC_FIQ_MODE_SELECT) |= ((1 << source_bit_index))
++
++/*-------------------------------------------------*/
++//                       PHY define
++/*-------------------------------------------------*/
++#define PHY_CONTROL_REG_ADDR		0x00
++#define PHY_STATUA_REG_ADDR		0x01
++#define PHY_ID1_REG_ADDR		0x02
++#define PHY_ID2_REG_ADDR		0x03
++#define PHY_AN_ADVERTISEMENT_REG_ADDR	0x04
++#define PHY_AN_REAMOTE_CAP_REG_ADDR	0x05
++#define PHY_RESERVED1_REG_ADDR		0x10
++#define PHY_RESERVED2_REG_ADDR		0x11
++#define PHY_CH_STATUS_OUTPUT_REG_ADDR	0x12
++#define PHY_RESERVED3_REG_ADDR		0x13
++#define PHY_RESERVED4_REG_ADDR		0x14
++
++#define PHY_LSI_L84225_ID1		0x0016
++#define PHY_LSI_L84225_ID2		0xF840	// 0xF870????
++
++//--------------------------------------------------------
++//         STAR9100 Hnat related define
++//--------------------------------------------------------
++/*Define for status print for Inerrrupt Status Register */
++#define INT_PORT0_Q_FULL		BIT(0)
++#define INT_PORT1_Q_FULL		BIT(1)
++#define INT_CPU_Q_FULL			BIT(2)
++#define INT_HNAT_Q_FULL			BIT(3)
++#define INT_GLOBAL_Q_FULL		BIT(4)
++#define INT_BUFFER_FULL			BIT(5)
++#define INT_PORT_STATUS_CHG		BIT(6)
++#define INT_INTRUDER0			BIT(7)
++#define INT_INTRUDER1			BIT(8)
++#define INT_CPU_HOLD			BIT(9)
++#define INT_PORT0_UNKNOWN_VLAN		BIT(10)
++#define INT_PORT1_UNKNOWN_VLAN		BIT(11)
++#define INT_CPU_UNKNOWN_VLAN		BIT(12)
++#define INT_PORT0_NO_LINK_DROP		BIT(16)
++#define INT_PORT0_BCS_DROP		BIT(17)
++#define INT_PORT0_RX_CRC_DROP		BIT(18)
++#define INT_PORT0_JAMED_DROP		BIT(19)
++#define INT_PORT0_QUEUE_DROP		BIT(20)
++#define INT_PORT0_RMC_DROP		BIT(21)
++#define INT_PORT0_LOCAL_DROP		BIT(22)
++#define INT_PORT0_INGRESS_DROP		BIT(23)
++#define INT_PORT1_NO_LINK_DROP		BIT(24)
++#define INT_PORT1_BCS_DROP		BIT(25)
++#define INT_PORT1_RX_CRC_DROP		BIT(26)
++#define INT_PORT1_JAMED_DROP		BIT(27)
++#define INT_PORT1_QUEUE_DROP		BIT(28)
++#define INT_PORT1_RMC_DROP		BIT(29)
++#define PORT1_LOCAL_DROP		BIT(30)
++#define PORT1_INGRESS_DROP		0x80000000
++
++#define MAX_VLAN_NUM			(8)
++#define MAX_PORT_NUM			(3)	/* including port 0, port 1, and CPU port */
++
++typedef struct _vlan_config_ {
++	u32	vlan_gid;	/* 3-bit VLAN group ID */
++	u32	vlan_vid;	/* 12-bit VLAN ID */
++	u32	vlan_group;	/* 3-bit VLAN group port map */
++	u32	vlan_tag_flag;	/* 3-bit VLAN tag port map */
++	u8	vlan_mac[6];
++	u8	pad[2];
++} vlan_config_t;
++
++typedef struct _port_config_ {
++	u32	pvid;	/* 3-bit Port PVID */
++	u32	config_flag;
++	u32	status_flag;
++} port_config_t;
++
++typedef struct _gsw_info_ {
++	vlan_config_t vlan[MAX_VLAN_NUM];
++	port_config_t port[MAX_PORT_NUM];
++} gsw_info_t;
++
++/* store this information for the driver.. */
++struct star_gsw_private {
++	struct net_device_stats stats;
++	spinlock_t lock;
++	/* Note:
++	 * device entry pmap = 0 means local loopback network interface
++	 * device entry pmap = 1 means GSW port 0 for LAN port network interface
++	 * device entry pmap = 2 means GSW port 1 for WAN port network interface
++	 * device entry pmap = 4 means GSW cpu port
++	 */
++	int pmap;
++	struct napi_struct  napi;
++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++        struct vlan_group               *vlgrp;
++#endif
++
++};
++
++#define __REG(reg)	(*(u32 volatile *)(reg))
++
++/*
++ * Network Driver, Receive/Send and Initial Buffer Function
++ */
++typedef struct {
++	// 1st 32Bits
++	u32 data_ptr;
++
++	// 2nd  32Bits
++	u32 length:16;
++	u32 tco:1;
++	u32 uco:1;
++	u32 ico:1;
++	u32 pmap:3;
++	u32 fr:1;
++	u32 pri:3;
++	u32 fp:1;
++	u32 interrupt:1;
++	u32 ls:1;
++	u32 fs:1;
++	u32 eor:1;
++	u32 cown:1;
++
++	// 3rd 32Bits
++	u32 vid:3;
++	u32 insv:1;
++	u32 sid:3;
++	u32 inss:1;
++	u32 unused:24;
++
++	// 4th 32Bits
++	u32 unused2;
++
++} __attribute__((packed)) STAR_GSW_TXDESC;
++
++typedef struct {
++	// 1st 32Bits
++	u32 data_ptr;
++
++	// 2nd  32Bits
++	u32 length:16;
++	u32 l4f:1;
++	u32 ipf:1;
++	u32 prot:2;
++	u32 hr:6;
++	u32 sp:2;
++	u32 ls:1;
++	u32 fs:1;
++	u32 eor:1;
++	u32 cown:1;
++
++	// 3rd 32Bits
++	u32 unused;
++
++	// 4th 32Bits
++	u32 unused2;
++
++} __attribute__((packed)) STAR_GSW_RXDESC;
++
++/* 
++ * Transmit Frame Descriptor Ring for TFDS
++ */
++
++typedef struct {
++	u32			phy_addr;
++	STAR_GSW_TXDESC		*vir_addr;
++	unsigned int		cur_index; // TX's current will point to Free Descriptors
++	struct sk_buff		*skb_ptr[STAR_GSW_MAX_TFD_NUM]; // TX's sk_buff ptr
++#if defined(FREE_TX_SKB_MULTI) || defined(STAR_GSW_TIMER)
++        u32                     to_free_index;
++#endif
++
++} TXRING_INFO;
++/* 
++ * Receive Frame Descriptor Ring for RFDS
++ */
++
++typedef struct {
++	u32			phy_addr;
++	STAR_GSW_RXDESC		*vir_addr;
++	u32			cur_index;
++	struct sk_buff		*skb_ptr[STAR_GSW_MAX_RFD_NUM];	// RX's sk_buff ptr
++} RXRING_INFO;
++
++extern void str9100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++
++/*
++ * data structure defines
++ */
++typedef struct _gsw_arl_table_entry_
++{
++    u32    filter;
++    u32    vlan_mac;
++    u32    vlan_gid;
++    u32    age_field;
++    u32    port_map;
++    u8     mac_addr[6];
++    u8     pad[2];
++
++} gsw_arl_table_entry_t;
++
++#endif
++
+diff -rupN linux-2.6.35.11/drivers/net/str9100/star_gsw_phy.c linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw_phy.c
+--- linux-2.6.35.11/drivers/net/str9100/star_gsw_phy.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw_phy.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,1224 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include "star_gsw_phy.h"
++#include "star_gsw.h"
++#include "star_gsw_config.h"
++
++
++#if 0
++void init_switch()
++{
++        u32 sw_config;
++
++	PDEBUG("init_switch\n");
++        /*
++         * Configure GSW configuration
++         */
++        sw_config = GSW_SWITCH_CONFIG;
++
++#if 0
++        // orignal virgon configuration
++        // enable fast aging
++        sw_config |= (0xF);
++
++        // CRC stripping
++        sw_config |= (0x1 << 21);
++
++        // IVL learning
++        sw_config |= (0x1 << 22);
++
++        // HNAT disable
++        sw_config &= ~(0x1 << 23);
++
++        GSW_SWITCH_CONFIG = sw_config;
++
++        sw_config = GSW_SWITCH_CONFIG;
++#endif
++
++        /* configure switch */
++        sw_config = GSW_SWITCH_CONFIG;
++
++        sw_config &= ~0xF;      /* disable aging */
++        sw_config |= 0x1;       /* disable aging */
++
++#ifdef JUMBO_ENABLE
++
++        // CRC stripping and GSW_CFG_MAX_LEN_JMBO
++        sw_config |= (GSW_CFG_CRC_STRP | GSW_CFG_MAX_LEN_JMBO);
++#else
++        // CRC stripping and 1536 bytes
++        sw_config |= (GSW_CFG_CRC_STRP | GSW_CFG_MAX_LEN_1536);
++#endif
++
++        /* IVL */
++        sw_config |= GSW_CFG_IVL;
++
++        /* disable HNAT */
++        sw_config &= ~GSW_CFG_HNAT_EN;
++
++        GSW_SWITCH_CONFIG = sw_config;
++}
++#endif
++
++
++
++
++
++
++// add by descent 2006/07/05
++// for configure packet forward and rate control
++void init_packet_forward(int port)
++{
++	u32 mac_port_config;
++
++	PDEBUG("port%d configure\n", port);
++	if (port==0)
++		mac_port_config = GSW_MAC_PORT_0_CONFIG;
++	if (port==1)
++		mac_port_config = GSW_MAC_PORT_1_CONFIG;
++	if (STR9100_GSW_BROADCAST_RATE_CONTROL)
++		mac_port_config |=  (0x1 << 31); // STR9100_GSW_BROADCAST_RATE_CONTROLL on
++	else
++		mac_port_config &=  (~(0x1 << 31)); // STR9100_GSW_BROADCAST_RATE_CONTROLL off
++
++	if (STR9100_GSW_MULTICAST_RATE_CONTROL)
++		mac_port_config |=  (0x1 << 30); // STR9100_GSW_MULTICAST_RATE_CONTROLL on
++	else
++		mac_port_config &=  (~(0x1 << 30)); // STR9100_GSW_MULTICAST_RATE_CONTROLL off
++
++	if (STR9100_GSW_UNKNOW_PACKET_RATE_CONTROL)
++		mac_port_config |=  (0x1 << 29); // STR9100_GSW_UNKNOW_PACKET_RATE_CONTROLL on
++	else
++		mac_port_config &=  (~(0x1 << 29)); // STR9100_GSW_UNKNOW_PACKET_RATE_CONTROLL off
++
++
++	if (STR9100_GSW_DISABLE_FORWARDING_BROADCAST_PACKET)
++		mac_port_config |=  (0x1 << 27); // STR9100_GSW_DISABLE_FORWARDING_BROADCAST_PACKET on
++	else
++		mac_port_config &=  (~(0x1 << 27)); // STR9100_GSW_DISABLE_FORWARDING_BROADCAST_PACKET off
++
++	if(STR9100_GSW_DISABLE_FORWARDING_MULTICAST_PACKET)
++	{
++		mac_port_config |=  (0x1 << 26); // STR9100_GSW_DISABLE_FORWARDING_MULTICAST_PACKET on
++		PDEBUG("STR9100_GSW_DISABLE_FORWARDING_MULTICAST_PACKET on\n");
++	}
++	else
++	{
++		mac_port_config &=  (~(0x1 << 26)); // STR9100_GSW_DISABLE_FORWARDING_MULTICAST_PACKET off
++		PDEBUG("STR9100_GSW_DISABLE_FORWARDING_MULTICAST_PACKET off\n");
++	}
++
++	if(STR9100_GSW_DISABLE_FORWARDING_UNKNOW_PACKET)
++		mac_port_config |=  (0x1 << 25); // STR9100_GSW_DISABLE_FORWARDING_UNKNOW_PACKET on
++	else
++		mac_port_config &=  (~(0x1 << 25)); // STR9100_GSW_DISABLE_FORWARDING_UNKNOW_PACKET off
++
++	//GSW_MAC_PORT_0_CONFIG = mac_port_config;
++	if (port==0)
++		GSW_MAC_PORT_0_CONFIG = mac_port_config;
++	if (port==1)
++		GSW_MAC_PORT_1_CONFIG = mac_port_config;
++}
++
++static int star_gsw_set_phy_addr(u8 mac_port, u8 phy_addr)
++{
++	u32 status = 0;	/* for failure indication */
++
++	if ((mac_port > 1) || (phy_addr > 31)) {
++		return status;
++	}
++
++	if (mac_port == 0) {
++		GSW_PORT_MIRROR &= ~(0x3 << 0); /* clear bit[1:0] for PHY_ADDR[1:0] */
++		GSW_PORT_MIRROR &= ~(0x3 << 4); /* clear bit[5:4] for PHY_ADDR[3:2] */
++		GSW_QUEUE_STATUS_TEST_1 &= ~(0x1 << 25); /* clear bit[25] for PHY_ADDR[4] */
++		GSW_PORT_MIRROR |= (((phy_addr >> 0) & 0x3) << 0);
++		GSW_PORT_MIRROR |= (((phy_addr >> 2) & 0x3) << 4);
++		GSW_QUEUE_STATUS_TEST_1 |= (((phy_addr >> 4) & 0x1) << 25);
++		status = 1; /* for ok indication */
++	} else if (mac_port == 1) {
++		GSW_PORT_MIRROR &= ~(0x1 << 6); /* clear bit[6] for PHY_ADDR[0] */
++		GSW_PORT_MIRROR &= ~(0x7 << 8); /* clear bit[10:8] for PHY_ADDR[3:1] */
++		GSW_QUEUE_STATUS_TEST_1 &= ~(0x1 << 26); /* clear bit[26] for PHY_ADDR[4] */
++		GSW_PORT_MIRROR |= (((phy_addr >> 0) & 0x1) << 6);
++		GSW_PORT_MIRROR |= (((phy_addr >> 1) & 0x7) << 8);
++		GSW_QUEUE_STATUS_TEST_1 |= (((phy_addr >> 4) & 0x1) << 26);
++		status = 1; /* for ok indication */
++	}
++
++	return status;
++}
++
++static int star_gsw_read_phy(u8 phy_addr, u8 phy_reg, u16 *read_data)
++{
++	u32 status;
++	int i;
++
++	// clear previous rw_ok status
++	GSW_PHY_CONTROL = (0x1 << 15);
++
++        // 20061013 descent 
++	// for ORION EOC
++        GSW_QUEUE_STATUS_TEST_1 &= ~( 0XF << 16);
++
++        GSW_PHY_CONTROL   &= ~(0x1<<0);
++
++        GSW_QUEUE_STATUS_TEST_1 |= (((phy_addr >> 1) & 0xF) << 16);
++        // 20061013 descent end
++
++
++	GSW_PHY_CONTROL = ((phy_addr & 0x1) | ((phy_reg & 0x1F) << 8) | (0x1 << 14));
++
++	for (i = 0; i < 0x1000; i++) {
++		status = GSW_PHY_CONTROL;
++		if (status & (0x1 << 15)) {
++			// clear the rw_ok status, and clear other bits value
++			GSW_PHY_CONTROL = (0x1 << 15);
++			*read_data = (u16) ((status >> 16) & 0xFFFF);
++			return (1);
++		} else {
++			udelay(10);
++		}
++	}
++
++	return (0);
++}
++
++static int star_gsw_write_phy(u8 phy_addr, u8 phy_reg, u16 write_data)
++{
++	int i;
++
++	// clear previous rw_ok status
++	GSW_PHY_CONTROL = (0x1 << 15);
++
++        // 20061013 descent 
++	// for ORION EOC
++        GSW_QUEUE_STATUS_TEST_1 &= ~( 0XF << 16);
++
++        GSW_PHY_CONTROL   &= ~(0x1<<0);
++
++        GSW_QUEUE_STATUS_TEST_1 |= (((phy_addr >> 1) & 0xF) << 16);
++        // 20061013 descent end
++
++
++	GSW_PHY_CONTROL = ((phy_addr & 0x1) |
++		((phy_reg & 0x1F) << 8) |
++		(0x1 << 13) | ((write_data & 0xFFFF) << 16));
++
++	for (i = 0; i < 0x1000; i++) {
++		if ((GSW_PHY_CONTROL) & (0x1 << 15)) {
++			// clear the rw_ok status, and clear other bits value
++			GSW_PHY_CONTROL = (0x1 << 15);
++			return (1);
++		} else {
++			udelay(10);
++		}
++	}
++
++	return (0);
++}
++
++#ifdef DORADO2_PCI_FASTPATH_MAC_PORT1_LOOPBACK
++static int star_gsw_config_mac_port1_loopback(void)
++{
++	u32 mac_port_base;
++	u32 mac_port_config;
++	int i;
++
++	PRINT_INFO("\nconfigure mac port1 loopback\n");
++	
++	mac_port_base = GSW_PORT1_CFG_REG;
++
++	mac_port_config = __REG(mac_port_base);
++
++	// disable PHY's AN
++	mac_port_config &= ~(0x1 << 7);
++
++	// enable RGMII-PHY mode
++	mac_port_config |= (0x1 << 15);
++
++	// reversed RGMII mode
++	mac_port_config |= (0x1 << 14);
++
++	// enable GSW MAC port 0
++	mac_port_config &= ~(0x1 << 18);
++
++	__REG(mac_port_base) = mac_port_config;
++
++	// SA learning disable
++	mac_port_config |= (0x1 << 19);
++
++	// disable TX flow control
++	mac_port_config &= ~(0x1 << 12);
++
++	// disable RX flow control
++	mac_port_config &= ~(0x1 << 11);
++
++	// force duplex
++	mac_port_config |= (0x1 << 10);
++
++	// force speed at 1000Mbps
++	mac_port_config &= ~(0x3 << 8);
++	mac_port_config |= (0x2 << 8);
++
++	__REG(mac_port_base) = mac_port_config;
++
++	// adjust MAC port 1 RX/TX clock skew
++	GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 28) | (0x3 << 30));
++	//GSW_BIST_RESULT_TEST_0 |= ((0x2 << 28) | (0x2 << 30));
++	GSW_BIST_RESULT_TEST_0 |= (0x2 << 30);
++
++	return 0;
++}
++#endif
++
++int VSC8201_phy_power_down(int phy_addr, int y)
++{
++	u16 phy_data = 0;
++	// power-down or up the PHY
++	star_gsw_read_phy(phy_addr, 0, &phy_data);
++	if (y==1) // down
++		phy_data |= (0x1 << 11);
++	if (y==0) // up
++		phy_data |= (~(0x1 << 11));
++	star_gsw_write_phy(phy_addr, 0, phy_data);
++	return 0;
++
++}
++
++static int star_gsw_config_VSC8201(u8 mac_port, u8 phy_addr)	// include cicada 8201
++{
++	u32 mac_port_base = 0;
++	u32 mac_port_config;
++	u16 phy_reg;
++	int i;
++
++	PRINT_INFO("\nconfigure VSC8201\n");
++	PDEBUG("mac port : %d phy addr : %d\n", mac_port, phy_addr);
++	/*
++	 * Configure MAC port 0
++	 * For Cicada CIS8201 single PHY
++	 */
++	if (mac_port == 0) {
++		PDEBUG("port 0\n");
++		mac_port_base = GSW_PORT0_CFG_REG;
++	}
++	if (mac_port == 1) {
++		PDEBUG("port 1\n");
++		mac_port_base = GSW_PORT1_CFG_REG;
++	}
++
++	star_gsw_set_phy_addr(mac_port, phy_addr);
++	//star_gsw_set_phy_addr(1, 1);
++
++	mac_port_config = __REG(mac_port_base);
++
++	// enable PHY's AN
++	mac_port_config |= (0x1 << 7);
++
++	// enable RGMII-PHY mode
++	mac_port_config |= (0x1 << 15);
++
++	// enable GSW MAC port 0
++	mac_port_config &= ~(0x1 << 18);
++
++	__REG(mac_port_base)=  mac_port_config;
++
++	/*
++	 * Configure Cicada's CIS8201 single PHY
++	 */
++	/* 2007.04.24 Richard.Liu Marked, we don't need VSC8201 lookback mode */
++#if 0
++#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++	/* near-end loopback mode */
++	star_gsw_read_phy(phy_addr, 0x0, &phy_reg);
++	phy_reg |= (0x1 << 14);
++	star_gsw_write_phy(phy_addr, 0x0, phy_reg);
++#endif
++#endif
++
++	star_gsw_read_phy(phy_addr, 0x1C, &phy_reg);
++
++	// configure SMI registers have higher priority over MODE/FRC_DPLX, and ANEG_DIS pins
++	phy_reg |= (0x1 << 2);
++
++	star_gsw_write_phy(phy_addr, 0x1C, phy_reg);
++
++	star_gsw_read_phy(phy_addr, 0x17, &phy_reg);
++
++	// enable RGMII MAC interface mode
++	phy_reg &= ~(0xF << 12);
++	phy_reg |= (0x1 << 12);
++
++	// enable RGMII I/O pins operating from 2.5V supply
++	phy_reg &= ~(0x7 << 9);
++	phy_reg |= (0x1 << 9);
++
++	star_gsw_write_phy(phy_addr, 0x17, phy_reg);
++
++	star_gsw_read_phy(phy_addr, 0x4, &phy_reg);
++
++	// Enable symmetric Pause capable
++	phy_reg |= (0x1 << 10);
++
++	star_gsw_write_phy(phy_addr, 0x4, phy_reg);
++
++	mac_port_config = __REG(mac_port_base);
++
++	/* 2007.04.24 Richard.Liu Marked, we don't need VSC8201 lookback mode */
++//#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++#if 0
++	// near-end loopback mode, must disable AN
++	mac_port_config &= ~(0x1 << 7);
++
++	// SA learning disable
++	mac_port_config |= (0x1 << 19);
++
++	// disable TX flow control
++	mac_port_config &= ~(0x1 << 12);
++
++	// disable RX flow control
++	mac_port_config &= ~(0x1 << 11);
++
++	// force duplex
++	mac_port_config |= (0x1 << 10);
++
++	// force speed at 1000Mpbs
++	mac_port_config &= ~(0x3 << 8);
++	mac_port_config |= (0x2 << 8);
++#else
++	// enable PHY's AN
++	mac_port_config |= (0x1 << 7);
++#endif
++
++	__REG(mac_port_base) = mac_port_config;
++
++	/*
++	 * Enable PHY1 AN restart bit to restart PHY1 AN
++	 */
++	star_gsw_read_phy(phy_addr, 0x0, &phy_reg);
++
++	phy_reg |= (0x1 << 9) | (0x1 << 12);
++
++	star_gsw_write_phy(phy_addr, 0x0, phy_reg);
++
++	/*
++	 * Polling until PHY0 AN restart is complete
++	 */
++	for (i = 0; i < 0x1000; i++) {
++		star_gsw_read_phy(phy_addr, 0x1, &phy_reg);
++
++		if ((phy_reg & (0x1 << 5)) && (phy_reg & (0x1 << 2))) {
++			printk("0x1 phy reg: %x\n", phy_reg);
++			break;
++		} else {
++			udelay(100);
++		}
++	}
++
++	mac_port_config = __REG(mac_port_base);
++
++	if (((mac_port_config & 0x1) == 0) || (mac_port_config & 0x2)) {
++		printk("Check MAC/PHY%s Link Status : DOWN!\n", (mac_port == 0 ? "0" : "1"));
++	} else {
++		printk("Check MAC/PHY%s Link Status : UP!\n", (mac_port == 0 ? "0" : "1"));
++		/*
++		 * There is a bug for CIS8201 PHY operating at 10H mode, and we use the following
++		 * code segment to work-around
++		 */
++		star_gsw_read_phy(phy_addr, 0x05, &phy_reg);
++
++		if ((phy_reg & (0x1 << 5)) && (!(phy_reg & (0x1 << 6))) && (!(phy_reg & (0x1 << 7))) && (!(phy_reg & (0x1 << 8)))) {	/* 10H,10F/100F/100H off */
++			star_gsw_read_phy(phy_addr, 0x0a, &phy_reg);
++
++			if ((!(phy_reg & (0x1 << 10))) && (!(phy_reg & (0x1 << 11)))) {	/* 1000F/1000H off */
++				star_gsw_read_phy(phy_addr, 0x16, &phy_reg);
++
++				phy_reg |= (0x1 << 13) | (0x1 << 15);	// disable "Link integrity check(B13)" & "Echo mode(B15)"
++
++				star_gsw_write_phy(phy_addr, 0x16, phy_reg);
++			}
++		}
++	}
++
++	if (mac_port == 0) {
++		// adjust MAC port 0 RX/TX clock skew
++		GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 24) | (0x3 << 26));
++		GSW_BIST_RESULT_TEST_0 |= ((0x2 << 24) | (0x2 << 26));
++	}
++
++	if (mac_port == 1) {
++		// adjust MAC port 1 RX/TX clock skew
++		GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 28) | (0x3 << 30));
++		GSW_BIST_RESULT_TEST_0 |= ((0x2 << 28) | (0x2 << 30));
++	}
++
++	return 0;
++}
++
++// add by descent 2006/07/10
++// port : 0 => port0 ; port : 1 => port1
++// y = 1 ; disable AN
++int disable_AN(int port, int y)
++{
++	u32 mac_port_config;
++	if (port==0)
++		mac_port_config = GSW_MAC_PORT_0_CONFIG;
++	if (port==1)
++		mac_port_config = GSW_MAC_PORT_1_CONFIG;
++	// disable PHY's AN
++	if (y==1)
++	{
++	  PDEBUG("disable AN\n");
++	  mac_port_config &= ~(0x1 << 7);
++	}
++
++	// enable PHY's AN
++	if (y==0)
++	{
++	  PDEBUG("enable AN\n");
++	  mac_port_config |= (0x1 << 7);
++	}
++
++	if (port==0)
++		GSW_MAC_PORT_0_CONFIG = mac_port_config;
++	if (port==1)
++		GSW_MAC_PORT_1_CONFIG = mac_port_config;
++	return 0;
++}
++
++int disable_AN_VSC7385(int y)
++{
++	u32 mac_port_config;
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++
++	// disable PHY's AN
++	if (y==1)
++	{
++	  PDEBUG("disable AN\n");
++	  mac_port_config &= ~(0x1 << 7);
++	}
++
++	// enable PHY's AN
++	if (y==0)
++	{
++	  PDEBUG("enable AN\n");
++	  mac_port_config |= (0x1 << 7);
++	}
++
++	GSW_MAC_PORT_0_CONFIG = mac_port_config;
++	return 0;
++}
++
++void star_gsw_config_VSC7385(void)
++{
++	u32 mac_port_config;
++
++
++	printk("\nconfigure VSC7385\n");
++	/*
++	 * Configure GSW's MAC port 0
++	 * For ASIX's 5-port GbE Switch setting
++	 * 1. No SMI (MDC/MDIO) connection between Orion's MAC port 0 and ASIX's MAC port 4
++	 * 2. Force Orion's MAC port 0 to be 1000Mbps, and full-duplex, and flow control on
++	 */
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++
++
++	// enable RGMII-PHY mode
++	mac_port_config |= (0x1 << 15);
++
++	// force speed = 1000Mbps
++	mac_port_config &= ~(0x3 << 8);
++	mac_port_config |= (0x2 << 8);
++
++	// force full-duplex
++	mac_port_config |= (0x1 << 10);
++
++	// force Tx/Rx flow-control on
++	mac_port_config |= (0x1 << 11) | (0x1 << 12);
++
++	GSW_MAC_PORT_0_CONFIG = mac_port_config;
++
++	udelay(1000);
++
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++
++	if (((mac_port_config & 0x1) == 0) || (mac_port_config & 0x2)) {
++		printk("Check MAC/PHY 0 Link Status : DOWN!\n");
++	} else {
++		printk("Check MAC/PHY 0 Link Status : UP!\n");
++	}
++
++	/* adjust MAC port 0 /RX/TX clock skew */
++	GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 24) | (0x3 << 26));
++	GSW_BIST_RESULT_TEST_0 |= ((0x2 << 24) | (0x2 << 26));
++}
++
++
++
++void star_gsw_config_ASIX()
++{
++	u32 mac_port_config;
++
++	printk("configure port0 ASIX\n");
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++
++	//Disable AN
++	mac_port_config &= (~(0x1 << 7));
++
++	//force speed to 1000Mbps
++	mac_port_config &= (~(0x3 << 8));
++	mac_port_config |= (0x2 << 8);	//jacky
++
++	//force tx and rx follow control
++	mac_port_config |= (0x1 << 11) | (0x1 << 12);
++
++	//force full deplex
++	mac_port_config |= 0x1 << 10;
++
++	//RGMII ENABLR
++	mac_port_config |= 0x1 << 15;
++
++	GSW_MAC_PORT_0_CONFIG = mac_port_config;
++
++	udelay(1000);
++
++	/* adjust MAC port 0 RX/TX clock skew */
++	GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 24) | (0x3 << 26));
++	GSW_BIST_RESULT_TEST_0 |= ((0x2 << 24) | (0x2 << 26));
++	
++	// configure MAC port 0 pad drive strength = 10/100 mode
++	*(u32 volatile *) (0xf770001C) |= (0x1 << 2);
++}
++
++
++
++// agere power down/up
++int AGERE_phy_power_down(int phy_addr, int y)
++{
++	u16 phy_data = 0;
++	// power-down or up the PHY
++	star_gsw_read_phy(phy_addr, 0, &phy_data);
++	if (y==1) // down
++		phy_data |= (0x1 << 11);
++	if (y==0) // up
++		phy_data &= (~(0x1 << 11));
++	star_gsw_write_phy(phy_addr, 0, phy_data);
++	return 0;
++}
++
++// add by descent 2006/07/31
++// standard phy register 0 and offset is 11 is power down
++int std_phy_power_down(int phy_addr, int y)
++{
++	u16 phy_data = 0;
++	// power-down or up the PHY
++	star_gsw_read_phy(phy_addr, 0, &phy_data);
++	if (y==1) // down
++		phy_data |= (0x1 << 11);
++	if (y==0) // up
++		phy_data &= (~(0x1 << 11));
++	star_gsw_write_phy(phy_addr, 0, phy_data);
++	return 0;
++}
++
++
++/*
++ *  AGERE PHY is attached to MAC PORT 1
++ * with phy_addr 1
++ */
++void star_gsw_config_AGERE()
++{
++	u32 mac_port_config;
++	u16 phy_data = 0;
++	int i;
++
++	printk("configure port1 AGERE\n");
++
++	/*
++	 * Configure MAC port 1
++	 * For Agere Systems's ET1011 single PHY
++	 */
++	mac_port_config = GSW_MAC_PORT_1_CONFIG;
++
++	// disable PHY's AN
++	mac_port_config &= ~(0x1 << 7);
++
++	// enable RGMII-PHY mode
++	mac_port_config |= (0x1 << 15);
++
++	GSW_MAC_PORT_1_CONFIG = mac_port_config;
++
++#if 1
++	/*
++	 * configure Agere's ET1011 Single PHY
++	 */
++	/* Configure Agere's ET1011 by Agere's programming note */
++	//1. power-down the PHY
++	star_gsw_read_phy(1, 0, &phy_data);
++	phy_data |= (0x1 << 11);
++	star_gsw_write_phy(1, 0, phy_data);
++
++	//2. Enable PHY programming mode
++	star_gsw_read_phy(1, 18, &phy_data);
++	phy_data |= (0x1 << 0);
++	phy_data |= (0x1 << 2);
++	star_gsw_write_phy(1, 18, phy_data);
++
++	//3.Perform some PHY register with the Agere-specfic value
++	star_gsw_write_phy(1, 16, 0x880e);
++	star_gsw_write_phy(1, 17, 0xb4d3);
++
++	star_gsw_write_phy(1, 16, 0x880f);
++	star_gsw_write_phy(1, 17, 0xb4d3);
++
++	star_gsw_write_phy(1, 16, 0x8810);
++	star_gsw_write_phy(1, 17, 0xb4d3);
++
++	star_gsw_write_phy(1, 16, 0x8817);
++	star_gsw_write_phy(1, 17, 0x1c00);
++
++	star_gsw_write_phy(1, 16, 0x8805);
++	star_gsw_write_phy(1, 17, 0xb03e);
++
++	star_gsw_write_phy(1, 16, 0x8806);
++	star_gsw_write_phy(1, 17, 0xb03e);
++
++	star_gsw_write_phy(1, 16, 0x8807);
++	star_gsw_write_phy(1, 17, 0xff00);
++
++	star_gsw_write_phy(1, 16, 0x8808);
++	star_gsw_write_phy(1, 17, 0xe110);
++
++	star_gsw_write_phy(1, 16, 0x300d);
++	star_gsw_write_phy(1, 17, 0x0001);
++
++	//4. Disable PHY programming mode
++	star_gsw_read_phy(1, 18, &phy_data);
++	phy_data &= ~(0x1 << 0);
++	phy_data &= ~(0x1 << 2);
++	star_gsw_write_phy(1, 18, phy_data);
++
++	//5. power-up the PHY
++	star_gsw_read_phy(1, 0, &phy_data);
++	phy_data &= ~(0x1 << 11);
++	star_gsw_write_phy(1, 0, phy_data);
++
++	star_gsw_read_phy(1, 22, &phy_data);
++
++	// enable RGMII MAC interface mode : RGMII/RMII (dll delay or trace delay) mode
++	phy_data &= ~(0x7 << 0);
++
++	// phy_data |= (0x6 << 0); // RGMII/RMII dll delay mode : not work!!
++	phy_data |= (0x4 << 0);	// RGMII/RMII trace delay mode
++
++	star_gsw_write_phy(1, 22, phy_data);
++#endif
++
++	mac_port_config = GSW_MAC_PORT_1_CONFIG;
++
++	// enable PHY's AN
++	mac_port_config |= (0x1 << 7);
++
++	GSW_MAC_PORT_1_CONFIG = mac_port_config;
++
++	/*
++	 * Enable flow-control on (Symmetric PAUSE frame)
++	 */
++	star_gsw_read_phy(1, 0x4, &phy_data);
++
++	phy_data |= (0x1 << 10);
++
++	star_gsw_write_phy(1, 0x4, phy_data);
++
++	/*
++	 * Enable PHY1 AN restart bit to restart PHY1 AN
++	 */
++	star_gsw_read_phy(1, 0x0, &phy_data);
++
++	phy_data |= (0x1 << 9) | (0x1 << 12);
++
++	star_gsw_write_phy(1, 0x0, phy_data);
++
++	/*
++	 * Polling until PHY1 AN restart is complete and PHY1 link status is UP
++	 */
++	for (i = 0; i < 0x2000; i++) {
++		star_gsw_read_phy(1, 0x1, &phy_data);
++		if ((phy_data & (0x1 << 5)) && (phy_data & (0x1 << 2))) {
++			break;
++		}
++	}
++
++	// adjust MAC port 1 RX/TX clock skew
++	GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 28) | (0x3 << 30));
++	GSW_BIST_RESULT_TEST_0 |= ((0x2 << 28) | (0x3 << 30));
++
++	udelay(100);
++
++	mac_port_config = GSW_MAC_PORT_1_CONFIG;
++	if (!(mac_port_config & 0x1) || (mac_port_config & 0x2)) {
++		/*
++		 * Port 1 PHY link down or no TXC in Port 1
++		 */
++		PDEBUG("PHY1: Link Down, 0x%08x!\n", mac_port_config);
++		return;
++	}
++
++}
++
++
++
++int str9100_gsw_config_mac_port0()
++{
++        PDEBUG("str9100_gsw_config_mac_port0\n");
++        INIT_PORT0_PHY
++	INIT_PORT0_MAC
++        PORT0_LINK_DOWN
++        return 0;
++}
++
++int str9100_gsw_config_mac_port1()
++{
++        INIT_PORT1_PHY
++	INIT_PORT1_MAC
++        PORT1_LINK_DOWN
++        //PORT1_LINK_UP
++        return 0;
++}
++
++
++#define PHY_CONTROL_REG_ADDR 0x00
++#define PHY_AN_ADVERTISEMENT_REG_ADDR 0x04
++
++
++int icp_101a_init (int port)
++{
++	u32 mac_port_config;
++        u16 phy_data = 0;
++
++
++	PRINT_INFO("init IC+101A\n");
++
++	if (port == 0)		// port 0
++		mac_port_config = GSW_MAC_PORT_0_CONFIG;
++	if (port == 1)		// port 1
++		mac_port_config = GSW_MAC_PORT_1_CONFIG;
++
++	if (!(mac_port_config & (0x1 << 5))) {
++		if (!star_gsw_read_phy (port, PHY_AN_ADVERTISEMENT_REG_ADDR, &phy_data))
++	    	{
++			PDEBUG("\n PORT%d, enable local flow control capability Fail\n", port);
++			return (1);
++	    	}
++		else
++	    	{
++	      		// enable PAUSE frame capability
++			phy_data |= (0x1 << 10);
++
++	      		if (!star_gsw_write_phy (port, PHY_AN_ADVERTISEMENT_REG_ADDR, phy_data))
++			{
++				PDEBUG("\nPORT%d, enable PAUSE frame capability Fail\n", port);
++				return (1);
++			}
++	    	}
++	}
++
++
++	// restart PHY0 AN
++	if (!star_gsw_read_phy (port, PHY_CONTROL_REG_ADDR, &phy_data)) {
++		PDEBUG ("\n restart PHY%d AN Fail \n", port);
++		return (1);
++	}
++	else {
++		// enable PHY0 AN restart
++		phy_data |= (0x1 << 9);
++
++		if (!star_gsw_write_phy (port, PHY_CONTROL_REG_ADDR, phy_data)) {
++			PDEBUG ("\n  enable PHY0 AN restart \n");
++			return (1);
++		}
++	}
++
++
++
++	while (1)
++	{
++		PDEBUG ("\n Polling  PHY%d AN \n", port);
++		star_gsw_read_phy (port, PHY_CONTROL_REG_ADDR, &phy_data);
++
++		if (phy_data & (0x1 << 9)) {
++		  continue;
++		}
++		else {
++			PDEBUG ("\n PHY%d AN restart is complete \n", port);
++			break;
++		}
++	}
++
++	return 0;
++}
++
++#ifdef CONFIG_LIBRA
++void icp_175c_all_phy_power_down(int y)
++{
++	int i=0;
++
++	for (i=0 ; i < 5 ; ++i)
++		std_phy_power_down(i, y);
++
++}
++
++#define CONFIG_PORT0_5
++
++void configure_icplus_175c_phy(void)
++{
++	u32 volatile	II, jj;
++	u32 volatile	mac_port_config;
++	u16 volatile reg;
++	u32 volatile reg2;
++	int i=0;
++
++	//star_gsw_set_phy_addr(0, 0);
++	//star_gsw_set_phy_addr(1, 1);
++
++	printk("\n ICPLUS175C_PHY,enable PORT0 local flow control capability \n");
++	/* adjust MAC port 0 /RX/TX clock skew */
++	GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 24) | (0x3 << 26));
++	GSW_BIST_RESULT_TEST_0 |= ((0x2 << 24) | (0x2 << 26));
++
++// 20061117 descent
++	// auto polling default phy address is 0
++	// so set phy address to not exist address to avoid auto polling
++	// in STAR library board if no these code, port 0 link state will get half duplex
++	// port 1-4 get full duplex
++        if (star_gsw_set_phy_addr(0, 15))
++                printk ("star_gsw_set_phy_addr(0,2) is successful\n");
++        else
++                printk ("star_gsw_set_phy_addr(0,2) is fail\n");
++
++        if (star_gsw_set_phy_addr(1, 16))
++                printk ("star_gsw_set_phy_addr(1,3) is successful\n");
++        else
++                printk ("star_gsw_set_phy_addr(1,3) is fail\n");
++
++
++
++	#if 0
++	// for PHY_AN_ADVERTISEMENT_REG_ADDR
++	// in this case needn't this code, only for reference
++		star_gsw_read_phy(i, 4, &phy_data);
++		phy_data |= (0x1 << 10);  // Enable PAUSE frame capability of PHY 0
++		phy_data |= (0x1 << 5) | (0x1 << 6) | (0x1 << 7) | (0x1 << 8);
++		star_gsw_write_phy(i, 4, phy_data);
++		star_gsw_read_phy(i, 0, &phy_data);
++		phy_data |= (0x1 << 9) | (0x1 << 12);  // Enable AN and Restart-AN
++		star_gsw_write_phy(i, 0, phy_data);
++	#endif
++// 20061117 descent end
++
++
++#if 0
++	for (i=0 ; i < 10; ++i)
++	{
++	  star_gsw_read_phy(i, 2, &reg);
++	  printk("addr: %d, phyid: %x\n", i, reg);
++	}
++
++
++
++
++	/*
++	 * Configure GSW's MAC port 0
++	 * For ASIX's 5-port GbE Switch setting
++	 * 1. No SMI (MDC/MDIO) connection between Orion's MAC port 0 and ASIX's MAC port 4
++	 * 2. Force Orion's MAC port 0 to be 1000Mbps, and full-duplex, and flow control on
++	 */
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++
++
++
++	// enable RGMII-PHY mode
++	mac_port_config &= ~(0x1 << 15);
++
++	// force speed = 100Mbps
++	mac_port_config &= ~(0x3 << 8);
++	mac_port_config |= (0x1 << 8);
++
++	// force full-duplex
++	mac_port_config |= (0x1 << 10);
++
++	// force Tx/Rx flow-control on
++	mac_port_config |= (0x1 << 11) | (0x1 << 12);
++
++	GSW_MAC_PORT_0_CONFIG = mac_port_config;
++	star_gsw_write_phy(29, 31, 0x175C);
++	//star_gsw_write_phy(30, 9, 0x1089);
++	star_gsw_write_phy(29, 23, 0x2);
++
++	star_gsw_write_phy(29, 24, 0x2);
++	star_gsw_write_phy(29, 25, 0x1);
++	star_gsw_write_phy(29, 26, 0x1);
++	star_gsw_write_phy(29, 27, 0x1);
++	star_gsw_write_phy(29, 28, 0x1);
++	star_gsw_write_phy(29, 29, 0x2);
++
++	star_gsw_write_phy(30, 1, (0x3e << 8) );
++	star_gsw_write_phy(30, 2, 0x21);
++	star_gsw_write_phy(30, 9, 0x80);
++
++	udelay(1000);
++
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++
++	if (((mac_port_config & 0x1) == 0) || (mac_port_config & 0x2)) {
++		printk("Check MAC/PHY 0 Link Status : DOWN!\n");
++	} else {
++		printk("Check MAC/PHY 0 Link Status : UP!\n");
++	}
++
++	/* adjust MAC port 0 /RX/TX clock skew */
++	GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 24) | (0x3 << 26));
++	GSW_BIST_RESULT_TEST_0 |= ((0x2 << 24) | (0x2 << 26));
++
++
++#endif
++
++
++
++#if 1
++
++	
++#if 1
++	reg2 = __REG(PWR_PAD_DRV_REG);
++	PDEBUG("[PWR_PAD_DRV_REG = %x]\n", reg2);
++	reg2 = reg2 | 0x4;
++
++	__REG(PWR_PAD_DRV_REG) = reg2;
++
++	reg2 = __REG(PWR_PAD_DRV_REG);
++	PDEBUG("[PWR_PAD_DRV_REG = %x]\n", reg2);
++#endif
++	
++	star_gsw_write_phy(29, 31, 0x175C);
++	
++
++	star_gsw_read_phy(0, 2, &reg);
++	PDEBUG("[0,%d,%x]\n", 2, reg);
++	star_gsw_read_phy(29, 31, &reg);
++	PDEBUG("[29,%d,%x]\n", 31, reg);
++
++	star_gsw_write_phy(29, 23, 0x7C2);
++	star_gsw_write_phy(29, 24, 0x1);
++	star_gsw_write_phy(29, 25, 0x1);
++	star_gsw_write_phy(29, 26, 0x1);
++
++#ifdef CONFIG_PORT0_5
++	star_gsw_write_phy(29, 27, 0x1);
++#else
++	star_gsw_write_phy(29, 27, 0x2);
++#endif
++	star_gsw_write_phy(29, 28, 0x2);
++	star_gsw_write_phy(29, 30, 0x2);
++
++#ifdef CONFIG_PORT0_5
++	printk("CONFIG_PORT0_5\n");
++	star_gsw_write_phy(30, 1, 0x2f00);
++	star_gsw_write_phy(30, 2, 0x30);
++#else // port0_4
++	printk("not CONFIG_PORT0_5\n");
++
++
++        //star_gsw_write_phy(30, 1, 0x2f00);
++        star_gsw_write_phy(30, 1, 0x2700);
++        //star_gsw_write_phy(30, 2, 0x30);
++        star_gsw_write_phy(30, 2, 0x38);
++
++#endif
++
++
++	star_gsw_write_phy(30, 9, 0x80);
++
++// 20061115 descent
++// If no these code,
++// in STAR libra board, will get crc drop
++	// configure port 4 (MII 0)
++	// configure port 4 (MII 0)
++
++	// P4_FORCE
++	star_gsw_read_phy(29, 22, &reg);
++	reg |= (0x1 << 15);
++        star_gsw_write_phy(29, 22, reg);
++
++	
++	// MAC_X_EN, flow control enable of MII0 and MII2
++	star_gsw_read_phy(29, 18, &reg);
++	reg |= (0x1 << 10);
++        star_gsw_write_phy(29, 18, reg);
++
++
++	// P4_FORCE 100 Mbps
++	star_gsw_read_phy(29, 22, &reg);
++	reg |= (0x1 << 10);
++        star_gsw_write_phy(29, 22, reg);
++
++
++	// P4_FORCE_FULL duplex
++	star_gsw_read_phy(29, 22, &reg);
++	reg |= (0x1 << 5);
++        star_gsw_write_phy(29, 22, reg);
++
++// 20061115 descent end
++
++
++
++
++
++	
++	#if 0
++	// enable flow control
++	star_gsw_read_phy(29, 18, &reg);
++	reg |= (0x1 < 13);
++	star_gsw_write_phy(29, 18, reg);
++	star_gsw_read_phy(29, 18, &reg);
++	printk("[29,%d,%x]\n", 18, reg);
++	#endif
++#if 0
++	//star_gsw_read_phy(29, 23, &reg);
++	//reg = reg & 0xF800;
++	//reg = reg | 0x7C2;
++
++
++	star_gsw_write_phy(29, 24, 0x1);
++
++	star_gsw_read_phy(29, 24, &reg);
++	PDEBUG("[  29, 24, %x]\n", reg);
++
++	star_gsw_write_phy(29, 25, 0x2);
++	udelay(1000);
++
++	star_gsw_read_phy(29, 25, &reg);
++	PDEBUG("[  29, 25, %x]\n", reg);
++
++	star_gsw_write_phy(29, 26, 0x1);
++	star_gsw_write_phy(29, 27, 0x1);
++	star_gsw_write_phy(29, 28, 0x1);
++	star_gsw_write_phy(29, 30, 0x2);
++
++	// tag vlan mask
++
++	star_gsw_write_phy(30, 1, 0x3F3D);
++
++	star_gsw_write_phy(30, 2, 0x3F22);
++	star_gsw_write_phy(30, 9, 0x1089);
++	// star_gsw_write_phy(30, 1, 0x3D22);
++	// star_gsw_write_phy(30, 9, 0x028A);
++#endif
++
++#if 0
++
++	for(II=18;II<=30;II++)
++	{
++		star_gsw_read_phy(29, II, &reg);
++		PDEBUG("[29,%d,%x]\n", II, reg);
++	}
++
++	for(II=1;II<=10;II++)
++	{
++		star_gsw_read_phy(30, II, &reg);
++		PDEBUG("[30,%d,%x]\n", II, reg);
++	}
++
++#endif
++
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++
++	// disable PHY's AN
++	mac_port_config &= ~(0x1 << 7);
++
++	// disable RGMII-PHY mode
++	mac_port_config &= ~(0x1 << 15);
++
++	// force speed = 100Mbps
++	mac_port_config &= ~(0x3 << 8);
++	mac_port_config |= (0x1 << 8);
++	
++	// force full-duplex
++	mac_port_config |= (0x1 << 10);
++
++	// force Tx/Rx flow-control on
++	mac_port_config |= (0x1 << 11) | (0x1 << 12);
++
++	GSW_MAC_PORT_0_CONFIG = mac_port_config;
++
++
++#if 0
++	for (II = 0; II < 0x2000; II++)
++	{
++		mac_port_config = GSW_MAC_PORT_0_CONFIG;
++		
++		if ((mac_port_config & 0x1) && !(mac_port_config & 0x2))
++		{
++
++			/* enable MAC port 0
++			*/
++			mac_port_config &= ~(0x1 << 18);
++
++		
++			/*
++			* enable the forwarding of unknown, multicast and broadcast packets to CPU
++			*/
++			mac_port_config &= ~((0x1 << 25) | (0x1 << 26) | (0x1 << 27));
++		
++			/*
++			* include unknown, multicast and broadcast packets into broadcast storm
++			*/
++			mac_port_config |= ((0x1 << 29) | (0x1 << 30) | ((u32)0x1 << 31));
++			// mac_port_config |= ( (0x1 << 30) | ((u32)0x1 << 31));
++			
++			GSW_MAC_PORT_0_CONFIG = mac_port_config;
++			
++			break;
++		}
++	}
++#endif
++
++	if (!(mac_port_config & 0x1) || (mac_port_config & 0x2))
++	{
++		/*
++		* Port 0 PHY link down or no TXC in Port 0
++		*/
++		printk("\rCheck MAC/PHY 0 Link Status : DOWN!\n");
++		
++	}
++	else
++	{
++		printk("\rCheck MAC/PHY 0 Link Status : UP!\n");
++	}
++#endif
++
++	//printk("Found ICPLUS175C_PHY\n");
++}
++#endif
+diff -rupN linux-2.6.35.11/drivers/net/str9100/star_gsw_phy.h linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw_phy.h
+--- linux-2.6.35.11/drivers/net/str9100/star_gsw_phy.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw_phy.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,160 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __STAR_GSW_PHY_H__
++#define __STAR_GSW_PHY_H__
++
++#include <linux/version.h>
++
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,32)
++#define LINUX24 1
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++#define LINUX26 1
++#endif
++
++#include <linux/types.h>
++
++
++//#define CONFIG_VIRGO
++//#define CONFIG_DORADO
++//#define CONFIG_DORADO2
++//#define CONFIG_LEO
++//#undef CONFIG_VIRGO
++//#undef CONFIG_DORADO
++//#undef CONFIG_DORADO2
++//#undef CONFIG_LEO
++
++#ifdef CONFIG_LIBRA
++#include "libra.h"
++#endif
++
++#ifdef CONFIG_VELA
++#include "vela.h"
++#endif
++
++#ifdef CONFIG_DORADO2
++#include "dorado2.h"
++#endif
++
++#ifdef CONFIG_DORADO
++#include "dorado.h"
++#endif
++
++#ifdef CONFIG_LEO
++#include "leo.h"
++#endif
++
++#ifdef CONFIG_VIRGO
++#include "virgo.h"
++#endif
++
++
++void star_gsw_config_ASIX(void);
++void star_gsw_config_AGERE(void);
++int AGERE_phy_power_down(int phy_addr, int y);
++int disable_AN_VSC7385(int y);
++void star_gsw_config_VSC7385(void);
++
++
++
++
++void star_gsw_config_AGERE(void);
++
++int str9100_gsw_config_mac_port0(void);
++int str9100_gsw_config_mac_port1(void);
++
++
++
++#define PORT0				(1 << 0)	/* bit map : bit 0 */
++#define PORT1				(1 << 1)	/* bit map : bit 1 */
++#define CPU_PORT			(1 << 2)	/* bit map : bit 2 */
++
++#define VLAN0_GROUP_ID			(0)
++#define VLAN1_GROUP_ID			(1)
++#define VLAN2_GROUP_ID			(2)
++#define VLAN3_GROUP_ID			(3)
++#define VLAN4_GROUP_ID			(4)
++#define VLAN5_GROUP_ID			(5)
++#define VLAN6_GROUP_ID			(6)
++#define VLAN7_GROUP_ID			(7)
++
++#define PORT0_PVID			(VLAN1_GROUP_ID)
++#define PORT1_PVID			(VLAN2_GROUP_ID)
++#define CPU_PORT_PVID			(VLAN0_GROUP_ID)
++
++#define INVALID_PORT_BASE_PMAP_PORT -1
++
++
++#ifdef LINUX26
++#define GSW_MAC_PORT_0_CONFIG GSW_MAC_PORT_0_CONFIG_REG
++#define GSW_MAC_PORT_1_CONFIG GSW_MAC_PORT_1_CONFIG_REG
++#define GSW_PORT_MIRROR GSW_PORT_MIRROR_REG
++#define GSW_QUEUE_STATUS_TEST_1 GSW_QUEUE_STATUS_TEST_1_REG
++#define GSW_PHY_CONTROL GSW_PHY_CONTROL_REG
++#define GSW_BIST_RESULT_TEST_0 GSW_BIST_RESULT_TEST_0_REG
++#define GSW_PORT0_CFG_REG (SYSVA_GSW_BASE_ADDR + 0x08)
++#define GSW_PORT1_CFG_REG (SYSVA_GSW_BASE_ADDR + 0x0C)
++#define GSW_SWITCH_CONFIG GSW_SWITCH_CONFIG_REG
++#define GSW_ARL_TABLE_ACCESS_CONTROL_0 GSW_ARL_TABLE_ACCESS_CONTROL_0_REG
++#define GSW_ARL_TABLE_ACCESS_CONTROL_1 GSW_ARL_TABLE_ACCESS_CONTROL_1_REG
++#define GSW_ARL_TABLE_ACCESS_CONTROL_2 GSW_ARL_TABLE_ACCESS_CONTROL_2_REG
++#define GSW_VLAN_PORT_PVID GSW_VLAN_PORT_PVID_REG
++#define GSW_VLAN_VID_0_1 GSW_VLAN_VID_0_1_REG
++#define GSW_VLAN_VID_2_3 GSW_VLAN_VID_2_3_REG
++#define GSW_VLAN_VID_4_5 GSW_VLAN_VID_4_5_REG
++#define GSW_VLAN_VID_6_7 GSW_VLAN_VID_6_7_REG
++#define GSW_VLAN_MEMBER_PORT_MAP GSW_VLAN_MEMBER_PORT_MAP_REG
++#define GSW_VLAN_TAG_PORT_MAP GSW_VLAN_TAG_PORT_MAP_REG
++#define GSW_INTERRUPT_MASK GSW_INTERRUPT_MASK_REG
++#define GSW_INTERRUPT_STATUS GSW_INTERRUPT_STATUS_REG
++#define INTC_INTERRUPT_CLEAR_EDGE_TRIGGER INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG
++#define GSW_TS_DMA_CONTROL GSW_TS_DMA_CONTROL_REG
++#define GSW_FS_DMA_CONTROL GSW_FS_DMA_CONTROL_REG
++#define GSW_TS_DESCRIPTOR_POINTER GSW_TS_DESCRIPTOR_POINTER_REG
++#define GSW_TS_DESCRIPTOR_BASE_ADDR GSW_TS_DESCRIPTOR_BASE_ADDR_REG
++#define GSW_FS_DESCRIPTOR_POINTER GSW_FS_DESCRIPTOR_POINTER_REG
++#define GSW_FS_DESCRIPTOR_BASE_ADDR GSW_FS_DESCRIPTOR_BASE_ADDR_REG
++#define GSW_CPU_PORT_CONFIG GSW_CPU_PORT_CONFIG_REG
++#define INTC_INTERRUPT_MASK INTC_INTERRUPT_MASK_REG
++#define GSW_DELAYED_INTERRUPT_CONFIG GSW_DELAYED_INTERRUPT_CONFIG_REG
++#define GSW_HNAT_SOURCE_MAC_0_HIGH GSW_HNAT_SOURCE_MAC_0_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_0_LOW GSW_HNAT_SOURCE_MAC_0_LOW_REG
++#define GSW_HNAT_SOURCE_MAC_1_HIGH GSW_HNAT_SOURCE_MAC_1_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_1_LOW GSW_HNAT_SOURCE_MAC_1_LOW_REG
++#define GSW_HNAT_SOURCE_MAC_2_HIGH GSW_HNAT_SOURCE_MAC_2_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_2_LOW GSW_HNAT_SOURCE_MAC_2_LOW_REG
++#define GSW_HNAT_SOURCE_MAC_3_HIGH GSW_HNAT_SOURCE_MAC_3_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_3_LOW GSW_HNAT_SOURCE_MAC_3_LOW_REG
++#define GSW_HNAT_SOURCE_MAC_4_HIGH GSW_HNAT_SOURCE_MAC_4_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_4_LOW GSW_HNAT_SOURCE_MAC_4_LOW_REG
++#define GSW_HNAT_SOURCE_MAC_5_HIGH GSW_HNAT_SOURCE_MAC_5_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_5_LOW GSW_HNAT_SOURCE_MAC_5_LOW_REG
++#define GSW_HNAT_SOURCE_MAC_6_HIGH GSW_HNAT_SOURCE_MAC_6_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_6_LOW GSW_HNAT_SOURCE_MAC_6_LOW_REG
++#define GSW_HNAT_SOURCE_MAC_7_HIGH GSW_HNAT_SOURCE_MAC_7_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_7_LOW GSW_HNAT_SOURCE_MAC_7_LOW_REG
++#define PWRMGT_SOFTWARE_RESET_CONTROL PWRMGT_SOFTWARE_RESET_CONTROL_REG
++
++#endif
++
++#endif /* __STAR_GSW_PHY_H__ */
+diff -rupN linux-2.6.35.11/drivers/net/str9100/vela.h linux-2.6.35.11-ts7500/drivers/net/str9100/vela.h
+--- linux-2.6.35.11/drivers/net/str9100/vela.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/vela.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,167 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef VELA_H
++#define VELA_H
++
++// add by descent 2006/07/07
++#define VELA
++#ifdef VELA
++// init phy or switch chip
++#define INIT_PORT0_PHY icp_101a_init(0);
++#define INIT_PORT1_PHY icp_101a_init(1);
++
++// configure mac0/mac1 register
++#define INIT_PORT0_MAC init_packet_forward(0);
++#define INIT_PORT1_MAC init_packet_forward(1);
++
++#define PORT0_LINK_DOWN std_phy_power_down(0, 1);
++#define PORT0_LINK_UP std_phy_power_down(0, 0);
++
++#define PORT1_LINK_DOWN std_phy_power_down(1, 1);
++#define PORT1_LINK_UP std_phy_power_down(1, 0);
++
++#define CREATE_NET_DEV0 star_gsw_probe(LAN_PORT);
++#define CREATE_NET_DEV1 star_gsw_probe(WAN_PORT);
++#define CREATE_NET_DEV2
++
++
++#undef CONFIG_STR9100_VLAN_BASE
++#undef CONFIG_HAVE_VLAN_TAG
++
++#define CONFIG_STR9100_PORT_BASE
++// for port base, port base max is 2 port.
++// NET_DEV0 : rx->sp 0 (port 0)
++#define NET_DEV0 STAR_GSW_LAN_DEV
++// NET_DEV1 : rx->sp 1 (port 1)
++#define NET_DEV1 STAR_GSW_WAN_DEV
++
++// for star_gsw_send_packet
++// port base and vlan base packet flow
++#define PORT_BASE_PMAP_LAN_PORT PORT0
++#define PORT_BASE_PMAP_WAN_PORT PORT1
++#define PORT_BASE_PMAP_EWC_PORT INVALID_PORT_BASE_PMAP_PORT
++
++
++// OPEN_PORT include 2 actions
++// 1. enable mac port
++// 2. link up port
++#define OPEN_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV) { \
++		memcpy(dev->dev_addr, star_gsw_info.vlan[LAN_GID].vlan_mac, 6);\
++       		PRINT_INFO("open mac port 0\n");\
++	        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++       		/* enable port 0 */ \
++	        mac_port_config &= (~(0x1 << 18));\
++       		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++		PORT0_LINK_UP\
++	} \
++	if(dev == STAR_GSW_WAN_DEV) { \
++		memcpy(dev->dev_addr, star_gsw_info.vlan[WAN_GID].vlan_mac, 6);\
++       		PRINT_INFO("open mac port 1\n");\
++	        mac_port_config = GSW_MAC_PORT_1_CONFIG;\
++       		/* enable port 0 */ \
++	        mac_port_config &= (~(0x1 << 18));\
++       		GSW_MAC_PORT_1_CONFIG = mac_port_config;\
++		PORT1_LINK_UP\
++	} \
++}
++
++// CLOSE_PORT include 2 actions
++// 1. disable mac port
++// 2. link down port
++#define CLOSE_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV) { \
++       		PRINT_INFO("close mac port 0\n");\
++		PORT0_LINK_DOWN\
++	        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++       		/* disable port 0 */ \
++	        mac_port_config |= ((0x1 << 18));\
++       		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++	} \
++	if(dev == STAR_GSW_WAN_DEV) { \
++       		PRINT_INFO("close mac port 1\n");\
++		PORT1_LINK_DOWN\
++	        mac_port_config = GSW_MAC_PORT_1_CONFIG;\
++       		/* disable port 1 */ \
++	        mac_port_config |= ((0x1 << 18));\
++       		GSW_MAC_PORT_1_CONFIG = mac_port_config;\
++	} \
++}
++
++
++#define VLAN0_VID			(0x111)
++#define VLAN1_VID			(0x222)
++#define VLAN2_VID			(0x333)
++#define VLAN3_VID			(0x444)
++#define VLAN4_VID			(0x555)
++#define VLAN5_VID			(0x666)
++#define VLAN6_VID			(0x777)
++#define VLAN7_VID			(0x888)
++
++
++#define VLAN0_GROUP			(PORT0 | PORT1 | CPU_PORT)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++#define VLAN2_GROUP			(PORT1 | CPU_PORT)
++#define VLAN3_GROUP			(0)
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#define VLAN7_GROUP			(0)
++
++#define VLAN0_VLAN_TAG			(0)
++#define VLAN1_VLAN_TAG			(0)
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#define VLAN7_VLAN_TAG			(0)
++
++//#define PORT0_PVID			(VLAN0_GROUP_ID)
++//#define PORT1_PVID			(VLAN2_GROUP_ID)
++//#define CPU_PORT_PVID			(VLAN1_GROUP_ID)
++
++static u8 my_vlan0_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xcc, 0x11};
++static u8 my_vlan1_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xcc, 0x21};
++static u8 my_vlan2_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xcc, 0x31};
++static u8 my_vlan3_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xcc, 0x41};
++
++// this value is for hnat
++// GID is vlan group id
++#define LAN_GID 1
++#define WAN_GID 2
++
++
++#define MODEL "VELA"
++
++#endif // VELA
++
++#endif
++
+diff -rupN linux-2.6.35.11/drivers/net/str9100/virgo.h linux-2.6.35.11-ts7500/drivers/net/str9100/virgo.h
+--- linux-2.6.35.11/drivers/net/str9100/virgo.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/virgo.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,167 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef VIRGO_H
++#define VIRGO_H
++
++// add by descent 2006/07/07
++#define VIRGO
++#ifdef VIRGO
++// init phy or switch chip
++#define INIT_PORT0_PHY star_gsw_config_ASIX();
++#define INIT_PORT1_PHY star_gsw_config_AGERE();
++
++// configure mac0/mac1 register
++#define INIT_PORT0_MAC init_packet_forward(0);
++#define INIT_PORT1_MAC init_packet_forward(1);
++
++#define PORT0_LINK_DOWN disable_AN_VSC7385(0);
++#define PORT0_LINK_UP disable_AN_VSC7385(1);
++
++#define PORT1_LINK_DOWN AGERE_phy_power_down(1,1);
++#define PORT1_LINK_UP AGERE_phy_power_down(1,0);
++
++#define CREATE_NET_DEV0 star_gsw_probe(LAN_PORT);
++#define CREATE_NET_DEV1 star_gsw_probe(WAN_PORT);
++#define CREATE_NET_DEV2
++
++
++#undef CONFIG_STR9100_VLAN_BASE
++#undef CONFIG_HAVE_VLAN_TAG
++
++#define CONFIG_STR9100_PORT_BASE
++// for port base, port base max is 2 port.
++// NET_DEV0 : rx->sp 0 (port 0)
++#define NET_DEV0 STAR_GSW_LAN_DEV
++// NET_DEV1 : rx->sp 1 (port 1)
++#define NET_DEV1 STAR_GSW_WAN_DEV
++
++// for star_gsw_send_packet
++// port base and vlan base packet flow
++#define PORT_BASE_PMAP_LAN_PORT PORT0
++#define PORT_BASE_PMAP_WAN_PORT PORT1
++#define PORT_BASE_PMAP_EWC_PORT INVALID_PORT_BASE_PMAP_PORT
++
++#define MODEL "VIRGO"
++
++// OPEN_PORT include 2 actions
++// 1. enable mac port
++// 2. link up port
++#define OPEN_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV) { \
++		memcpy(dev->dev_addr, star_gsw_info.vlan[LAN_GID].vlan_mac, 6);\
++       		PRINT_INFO("open mac port 0\n");\
++	        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++       		/* enable port 0 */ \
++	        mac_port_config &= (~(0x1 << 18));\
++       		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++		PORT0_LINK_UP\
++	} \
++	if(dev == STAR_GSW_WAN_DEV) { \
++		memcpy(dev->dev_addr, star_gsw_info.vlan[WAN_GID].vlan_mac, 6);\
++       		PRINT_INFO("open mac port 1\n");\
++	        mac_port_config = GSW_MAC_PORT_1_CONFIG;\
++       		/* enable port 0 */ \
++	        mac_port_config &= (~(0x1 << 18));\
++       		GSW_MAC_PORT_1_CONFIG = mac_port_config;\
++		PORT1_LINK_UP\
++	} \
++}
++
++// CLOSE_PORT include 2 actions
++// 1. disable mac port
++// 2. link down port
++#define CLOSE_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV) { \
++       		PRINT_INFO("close mac port 0\n");\
++		PORT0_LINK_DOWN\
++	        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++       		/* disable port 0 */ \
++	        mac_port_config |= ((0x1 << 18));\
++       		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++	} \
++	if(dev == STAR_GSW_WAN_DEV) { \
++       		PRINT_INFO("close mac port 1\n");\
++		PORT1_LINK_DOWN\
++	        mac_port_config = GSW_MAC_PORT_1_CONFIG;\
++       		/* disable port 1 */ \
++	        mac_port_config |= ((0x1 << 18));\
++       		GSW_MAC_PORT_1_CONFIG = mac_port_config;\
++	} \
++}
++
++
++#define VLAN0_VID			(0x111)
++#define VLAN1_VID			(0x222)
++#define VLAN2_VID			(0x333)
++#define VLAN3_VID			(0x444)
++#define VLAN4_VID			(0x555)
++#define VLAN5_VID			(0x666)
++#define VLAN6_VID			(0x777)
++#define VLAN7_VID			(0x888)
++
++
++#define VLAN0_GROUP			(PORT0 | PORT1 | CPU_PORT)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++#define VLAN2_GROUP			(PORT1 | CPU_PORT)
++#define VLAN3_GROUP			(0)
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#define VLAN7_GROUP			(0)
++
++#define VLAN0_VLAN_TAG			(0)
++#define VLAN1_VLAN_TAG			(0)
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#define VLAN7_VLAN_TAG			(0)
++
++//#define PORT0_PVID			(VLAN0_GROUP_ID)
++//#define PORT1_PVID			(VLAN2_GROUP_ID)
++//#define CPU_PORT_PVID			(VLAN1_GROUP_ID)
++
++static u8 my_vlan0_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x11};
++static u8 my_vlan1_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x21};
++static u8 my_vlan2_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x31};
++static u8 my_vlan3_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x41};
++
++// this value is for hnat
++// GID is vlan group id
++#define LAN_GID 1
++#define WAN_GID 2
++
++
++
++#endif // VIRGO
++
++#endif
++
+diff -rupN linux-2.6.35.11/drivers/pci/setup-bus.c linux-2.6.35.11-ts7500/drivers/pci/setup-bus.c
+--- linux-2.6.35.11/drivers/pci/setup-bus.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/pci/setup-bus.c	2011-03-14 11:18:24.000000000 -0400
+@@ -76,6 +76,21 @@ static void __dev_sort_resources(struct
+ {
+ 	u16 class = dev->class >> 8;
+ 
++#if defined(CONFIG_ARCH_STR9100) || defined(CONFIG_ARCH_STR8100)
++		{
++		u16 cmd;
++
++		pci_read_config_word(dev, PCI_COMMAND, &cmd);
++		cmd |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
++		pci_write_config_word(dev, PCI_COMMAND, cmd);
++		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x8); //configure cache line size
++		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40); //configure latency timer
++		}
++
++		if (dev->vendor == 0xeeee)
++			return;
++#endif   
++   
+ 	/* Don't touch classless devices or host bridges or ioapics.  */
+ 	if (class == PCI_CLASS_NOT_DEFINED || class == PCI_CLASS_BRIDGE_HOST)
+ 		return;
+diff -rupN linux-2.6.35.11/drivers/serial/8250.c linux-2.6.35.11-ts7500/drivers/serial/8250.c
+--- linux-2.6.35.11/drivers/serial/8250.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/serial/8250.c	2011-03-14 11:18:24.000000000 -0400
+@@ -45,6 +45,16 @@
+ 
+ #include "8250.h"
+ 
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++#include <asm/arch/star_gpio.h>
++extern int __init_or_module gpio_direction_input(unsigned int);
++extern int __init_or_module gpio_direction_output(unsigned int, unsigned int);
++extern void gpio_set_value(unsigned int, unsigned int);
++extern int gpio_get_value(unsigned int);
++unsigned int gpio_cts = 0;
++unsigned int gpio_rts;
++#endif
++
+ #ifdef CONFIG_SPARC
+ #include "suncore.h"
+ #endif
+@@ -622,6 +632,7 @@ static void serial_icr_write(struct uart
+ 	serial_out(up, UART_ICR, value);
+ }
+ 
++#if !defined(CONFIG_ARCH_STR9100) && !defined(CONFIG_ARCH_STR8100)
+ static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
+ {
+ 	unsigned int value;
+@@ -633,6 +644,7 @@ static unsigned int serial_icr_read(stru
+ 
+ 	return value;
+ }
++#endif
+ 
+ /*
+  * FIFO support.
+@@ -738,6 +750,13 @@ static void disable_rsa(struct uart_8250
+ }
+ #endif /* CONFIG_SERIAL_8250_RSA */
+ 
++#if defined(CONFIG_ARCH_STR9100) || defined(CONFIG_ARCH_STR8100)
++static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
++{
++	up->port.type = PORT_16550A;
++	return;
++}
++#else
+ /*
+  * This is a quickie test to see how big the FIFO is.
+  * It doesn't work at all the time, more's the pity.
+@@ -1253,6 +1272,7 @@ static void autoconfig(struct uart_8250_
+ 	spin_unlock_irqrestore(&up->port.lock, flags);
+ 	DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
+ }
++#endif
+ 
+ static void autoconfig_irq(struct uart_8250_port *up)
+ {
+@@ -1447,6 +1467,15 @@ receive_chars(struct uart_8250_port *up,
+ ignore_char:
+ 		lsr = serial_inp(up, UART_LSR);
+ 	} while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
++   
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++	if (gpio_rts)
++	{
++		gpio_set_value(CONFIG_GPIO_RTS,0);	/* assert RTS */
++		gpio_rts = 0;
++	}
++#endif   
++   
+ 	spin_unlock(&up->port.lock);
+ 	tty_flip_buffer_push(tty);
+ 	spin_lock(&up->port.lock);
+@@ -1465,6 +1494,10 @@ static void transmit_chars(struct uart_8
+ 		return;
+ 	}
+ 	if (uart_tx_stopped(&up->port)) {
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++		if (gpio_cts)
++			return;
++#endif      
+ 		serial8250_stop_tx(&up->port);
+ 		return;
+ 	}
+@@ -1495,6 +1528,22 @@ static unsigned int check_modem_status(s
+ {
+ 	unsigned int status = serial_in(up, UART_MSR);
+ 
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++	unsigned int gpio_new_cts = gpio_get_value(CONFIG_GPIO_CTS);
++
++	if (!gpio_new_cts)
++		status |= UART_MSR_CTS;		/* Assert CTS */
++	else
++		status &= ~UART_MSR_CTS;	/* Deassert CTS */
++
++	/* CTS pin has been changed */
++	if (gpio_new_cts != gpio_cts)
++	{
++		status |= UART_MSR_DCTS;
++		gpio_cts = gpio_new_cts;
++	}
++#endif
++
+ 	status |= up->msr_saved_flags;
+ 	up->msr_saved_flags = 0;
+ 	if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
+@@ -1521,10 +1570,24 @@ static void serial8250_handle_port(struc
+ {
+ 	unsigned int status;
+ 	unsigned long flags;
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++	unsigned int iir;
++#endif
+ 
+ 	spin_lock_irqsave(&up->port.lock, flags);
+ 
+ 	status = serial_inp(up, UART_LSR);
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++		iir = serial_in(up, UART_IIR);
++
++		if ((iir & 0x6) == 0x6)
++			printk("Overrun error!\n");
++		else if (iir & 0x4)
++		{
++			gpio_set_value(CONFIG_GPIO_RTS,1);		
++			gpio_rts = 1;
++		}
++#endif
+ 
+ 	DEBUG_INTR("status = %x...", status);
+ 
+@@ -1819,7 +1882,19 @@ static void serial8250_set_mctrl(struct
+ 	unsigned char mcr = 0;
+ 
+ 	if (mctrl & TIOCM_RTS)
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++	{
+ 		mcr |= UART_MCR_RTS;
++		gpio_set_value(CONFIG_GPIO_RTS,0);	/* assert RTS */
++	}
++	else
++	{
++		mcr &= ~UART_MCR_RTS;
++		gpio_set_value(CONFIG_GPIO_RTS,1);	/* deassert RTS */
++	}
++#else
++		mcr |= UART_MCR_RTS;
++#endif
+ 	if (mctrl & TIOCM_DTR)
+ 		mcr |= UART_MCR_DTR;
+ 	if (mctrl & TIOCM_OUT1)
+@@ -1938,6 +2013,9 @@ static int serial8250_startup(struct uar
+ {
+ 	struct uart_8250_port *up = (struct uart_8250_port *)port;
+ 	unsigned long flags;
++#if !defined(CONFIG_ARCH_STR9100) && !defined(CONFIG_ARCH_STR8100)
++	unsigned char lsr;
++#endif   
+ 	unsigned char lsr, iir;
+ 	int retval;
+ 
+@@ -2107,6 +2185,7 @@ static int serial8250_startup(struct uar
+ 	if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST)
+ 		goto dont_test_tx_en;
+ 
++#if !defined(CONFIG_ARCH_STR9100) && !defined(CONFIG_ARCH_STR8100)   
+ 	/*
+ 	 * Do a quick test to see if we receive an
+ 	 * interrupt when we enable the TX irq.
+@@ -2125,6 +2204,7 @@ static int serial8250_startup(struct uar
+ 	} else {
+ 		up->bugs &= ~UART_BUG_TXEN;
+ 	}
++#endif
+ 
+ dont_test_tx_en:
+ 	spin_unlock_irqrestore(&up->port.lock, flags);
+@@ -2812,7 +2892,11 @@ serial8250_console_write(struct console
+ static int __init serial8250_console_setup(struct console *co, char *options)
+ {
+ 	struct uart_port *port;
++#if defined(CONFIG_ARCH_STR9100) || defined(CONFIG_ARCH_STR8100)
++	int baud = CONFIG_CONSOLE_BAUD_RATE;
++#else
+ 	int baud = 9600;
++#endif
+ 	int bits = 8;
+ 	int parity = 'n';
+ 	int flow = 'n';
+@@ -3023,6 +3107,7 @@ static int __devexit serial8250_remove(s
+ 	return 0;
+ }
+ 
++#if !defined(CONFIG_ARCH_STR9100) && !defined(CONFIG_ARCH_STR8100)
+ static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
+ {
+ 	int i;
+@@ -3050,12 +3135,15 @@ static int serial8250_resume(struct plat
+ 
+ 	return 0;
+ }
++#endif
+ 
+ static struct platform_driver serial8250_isa_driver = {
+ 	.probe		= serial8250_probe,
+ 	.remove		= __devexit_p(serial8250_remove),
++#if !defined(CONFIG_ARCH_STR9100) && !defined(CONFIG_ARCH_STR8100)
+ 	.suspend	= serial8250_suspend,
+ 	.resume		= serial8250_resume,
++#endif
+ 	.driver		= {
+ 		.name	= "serial8250",
+ 		.owner	= THIS_MODULE,
+@@ -3197,6 +3285,31 @@ static int __init serial8250_init(void)
+ {
+ 	int ret;
+ 
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++	/* enable GPIO pin function */
++	MISC_GPIOB_PIN_ENABLE_REG &= ~(1 << CONFIG_GPIO_CTS | 1 << CONFIG_GPIO_RTS | 1 << CONFIG_GPIO_DCD \
++						| 1<<CONFIG_GPIO_DTR | 1<<CONFIG_GPIO_DSR | 1<<CONFIG_GPIO_RI);
++
++	/* configure CTS pin (input) */
++	gpio_direction_input(CONFIG_GPIO_CTS);
++	gpio_cts = gpio_get_value(CONFIG_GPIO_CTS);
++
++	/* configure RTS pin (output) and set to high */
++	gpio_direction_output(CONFIG_GPIO_RTS,1);
++
++	/* configure DCD pin (input) */
++	gpio_direction_input(CONFIG_GPIO_DCD);
++
++	/* configure DTR pin (ouput) and set to low */
++	gpio_direction_output(CONFIG_GPIO_DTR,0);
++
++	/* configure DSR pin (input) */
++	gpio_direction_input(CONFIG_GPIO_DSR);
++
++	/* configure RI pin (input) */
++	gpio_direction_input(CONFIG_GPIO_RI);
++#endif
++
+ 	if (nr_uarts > UART_NR)
+ 		nr_uarts = UART_NR;
+ 
+diff -rupN linux-2.6.35.11/drivers/serial/8250.c.orig linux-2.6.35.11-ts7500/drivers/serial/8250.c.orig
+--- linux-2.6.35.11/drivers/serial/8250.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/serial/8250.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,3290 @@
++/*
++ *  linux/drivers/char/8250.c
++ *
++ *  Driver for 8250/16550-type serial ports
++ *
++ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
++ *
++ *  Copyright (C) 2001 Russell King.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * A note about mapbase / membase
++ *
++ *  mapbase is the physical address of the IO port.
++ *  membase is an 'ioremapped' cookie.
++ */
++
++#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
++#define SUPPORT_SYSRQ
++#endif
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/ioport.h>
++#include <linux/init.h>
++#include <linux/console.h>
++#include <linux/sysrq.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++#include <linux/serial_reg.h>
++#include <linux/serial_core.h>
++#include <linux/serial.h>
++#include <linux/serial_8250.h>
++#include <linux/nmi.h>
++#include <linux/mutex.h>
++#include <linux/slab.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++
++#include "8250.h"
++
++#ifdef CONFIG_SPARC
++#include "suncore.h"
++#endif
++
++/*
++ * Configuration:
++ *   share_irqs - whether we pass IRQF_SHARED to request_irq().  This option
++ *                is unsafe when used on edge-triggered interrupts.
++ */
++static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
++
++static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
++
++static struct uart_driver serial8250_reg;
++
++static int serial_index(struct uart_port *port)
++{
++	return (serial8250_reg.minor - 64) + port->line;
++}
++
++static unsigned int skip_txen_test; /* force skip of txen test at init time */
++
++/*
++ * Debugging.
++ */
++#if 0
++#define DEBUG_AUTOCONF(fmt...)	printk(fmt)
++#else
++#define DEBUG_AUTOCONF(fmt...)	do { } while (0)
++#endif
++
++#if 0
++#define DEBUG_INTR(fmt...)	printk(fmt)
++#else
++#define DEBUG_INTR(fmt...)	do { } while (0)
++#endif
++
++#define PASS_LIMIT	256
++
++#define BOTH_EMPTY 	(UART_LSR_TEMT | UART_LSR_THRE)
++
++
++/*
++ * We default to IRQ0 for the "no irq" hack.   Some
++ * machine types want others as well - they're free
++ * to redefine this in their header file.
++ */
++#define is_real_interrupt(irq)	((irq) != 0)
++
++#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
++#define CONFIG_SERIAL_DETECT_IRQ 1
++#endif
++#ifdef CONFIG_SERIAL_8250_MANY_PORTS
++#define CONFIG_SERIAL_MANY_PORTS 1
++#endif
++
++/*
++ * HUB6 is always on.  This will be removed once the header
++ * files have been cleaned.
++ */
++#define CONFIG_HUB6 1
++
++#include <asm/serial.h>
++/*
++ * SERIAL_PORT_DFNS tells us about built-in ports that have no
++ * standard enumeration mechanism.   Platforms that can find all
++ * serial ports via mechanisms like ACPI or PCI need not supply it.
++ */
++#ifndef SERIAL_PORT_DFNS
++#define SERIAL_PORT_DFNS
++#endif
++
++static const struct old_serial_port old_serial_port[] = {
++	SERIAL_PORT_DFNS /* defined in asm/serial.h */
++};
++
++#define UART_NR	CONFIG_SERIAL_8250_NR_UARTS
++
++#ifdef CONFIG_SERIAL_8250_RSA
++
++#define PORT_RSA_MAX 4
++static unsigned long probe_rsa[PORT_RSA_MAX];
++static unsigned int probe_rsa_count;
++#endif /* CONFIG_SERIAL_8250_RSA  */
++
++struct uart_8250_port {
++	struct uart_port	port;
++	struct timer_list	timer;		/* "no irq" timer */
++	struct list_head	list;		/* ports on this IRQ */
++	unsigned short		capabilities;	/* port capabilities */
++	unsigned short		bugs;		/* port bugs */
++	unsigned int		tx_loadsz;	/* transmit fifo load size */
++	unsigned char		acr;
++	unsigned char		ier;
++	unsigned char		lcr;
++	unsigned char		mcr;
++	unsigned char		mcr_mask;	/* mask of user bits */
++	unsigned char		mcr_force;	/* mask of forced bits */
++	unsigned char		cur_iotype;	/* Running I/O type */
++
++	/*
++	 * Some bits in registers are cleared on a read, so they must
++	 * be saved whenever the register is read but the bits will not
++	 * be immediately processed.
++	 */
++#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
++	unsigned char		lsr_saved_flags;
++#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
++	unsigned char		msr_saved_flags;
++
++	/*
++	 * We provide a per-port pm hook.
++	 */
++	void			(*pm)(struct uart_port *port,
++				      unsigned int state, unsigned int old);
++};
++
++struct irq_info {
++	struct			hlist_node node;
++	int			irq;
++	spinlock_t		lock;	/* Protects list not the hash */
++	struct list_head	*head;
++};
++
++#define NR_IRQ_HASH		32	/* Can be adjusted later */
++static struct hlist_head irq_lists[NR_IRQ_HASH];
++static DEFINE_MUTEX(hash_mutex);	/* Used to walk the hash */
++
++/*
++ * Here we define the default xmit fifo size used for each type of UART.
++ */
++static const struct serial8250_config uart_config[] = {
++	[PORT_UNKNOWN] = {
++		.name		= "unknown",
++		.fifo_size	= 1,
++		.tx_loadsz	= 1,
++	},
++	[PORT_8250] = {
++		.name		= "8250",
++		.fifo_size	= 1,
++		.tx_loadsz	= 1,
++	},
++	[PORT_16450] = {
++		.name		= "16450",
++		.fifo_size	= 1,
++		.tx_loadsz	= 1,
++	},
++	[PORT_16550] = {
++		.name		= "16550",
++		.fifo_size	= 1,
++		.tx_loadsz	= 1,
++	},
++	[PORT_16550A] = {
++		.name		= "16550A",
++		.fifo_size	= 16,
++		.tx_loadsz	= 16,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++		.flags		= UART_CAP_FIFO,
++	},
++	[PORT_CIRRUS] = {
++		.name		= "Cirrus",
++		.fifo_size	= 1,
++		.tx_loadsz	= 1,
++	},
++	[PORT_16650] = {
++		.name		= "ST16650",
++		.fifo_size	= 1,
++		.tx_loadsz	= 1,
++		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++	},
++	[PORT_16650V2] = {
++		.name		= "ST16650V2",
++		.fifo_size	= 32,
++		.tx_loadsz	= 16,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
++				  UART_FCR_T_TRIG_00,
++		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++	},
++	[PORT_16750] = {
++		.name		= "TI16750",
++		.fifo_size	= 64,
++		.tx_loadsz	= 64,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
++				  UART_FCR7_64BYTE,
++		.flags		= UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE,
++	},
++	[PORT_STARTECH] = {
++		.name		= "Startech",
++		.fifo_size	= 1,
++		.tx_loadsz	= 1,
++	},
++	[PORT_16C950] = {
++		.name		= "16C950/954",
++		.fifo_size	= 128,
++		.tx_loadsz	= 128,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++		.flags		= UART_CAP_FIFO,
++	},
++	[PORT_16654] = {
++		.name		= "ST16654",
++		.fifo_size	= 64,
++		.tx_loadsz	= 32,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
++				  UART_FCR_T_TRIG_10,
++		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++	},
++	[PORT_16850] = {
++		.name		= "XR16850",
++		.fifo_size	= 128,
++		.tx_loadsz	= 128,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++	},
++	[PORT_RSA] = {
++		.name		= "RSA",
++		.fifo_size	= 2048,
++		.tx_loadsz	= 2048,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11,
++		.flags		= UART_CAP_FIFO,
++	},
++	[PORT_NS16550A] = {
++		.name		= "NS16550A",
++		.fifo_size	= 16,
++		.tx_loadsz	= 16,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++		.flags		= UART_CAP_FIFO | UART_NATSEMI,
++	},
++	[PORT_XSCALE] = {
++		.name		= "XScale",
++		.fifo_size	= 32,
++		.tx_loadsz	= 32,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++		.flags		= UART_CAP_FIFO | UART_CAP_UUE,
++	},
++	[PORT_RM9000] = {
++		.name		= "RM9000",
++		.fifo_size	= 16,
++		.tx_loadsz	= 16,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++		.flags		= UART_CAP_FIFO,
++	},
++	[PORT_OCTEON] = {
++		.name		= "OCTEON",
++		.fifo_size	= 64,
++		.tx_loadsz	= 64,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++		.flags		= UART_CAP_FIFO,
++	},
++	[PORT_AR7] = {
++		.name		= "AR7",
++		.fifo_size	= 16,
++		.tx_loadsz	= 16,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
++		.flags		= UART_CAP_FIFO | UART_CAP_AFE,
++	},
++};
++
++#if defined (CONFIG_SERIAL_8250_AU1X00)
++
++/* Au1x00 UART hardware has a weird register layout */
++static const u8 au_io_in_map[] = {
++	[UART_RX]  = 0,
++	[UART_IER] = 2,
++	[UART_IIR] = 3,
++	[UART_LCR] = 5,
++	[UART_MCR] = 6,
++	[UART_LSR] = 7,
++	[UART_MSR] = 8,
++};
++
++static const u8 au_io_out_map[] = {
++	[UART_TX]  = 1,
++	[UART_IER] = 2,
++	[UART_FCR] = 4,
++	[UART_LCR] = 5,
++	[UART_MCR] = 6,
++};
++
++/* sane hardware needs no mapping */
++static inline int map_8250_in_reg(struct uart_port *p, int offset)
++{
++	if (p->iotype != UPIO_AU)
++		return offset;
++	return au_io_in_map[offset];
++}
++
++static inline int map_8250_out_reg(struct uart_port *p, int offset)
++{
++	if (p->iotype != UPIO_AU)
++		return offset;
++	return au_io_out_map[offset];
++}
++
++#elif defined(CONFIG_SERIAL_8250_RM9K)
++
++static const u8
++	regmap_in[8] = {
++		[UART_RX]	= 0x00,
++		[UART_IER]	= 0x0c,
++		[UART_IIR]	= 0x14,
++		[UART_LCR]	= 0x1c,
++		[UART_MCR]	= 0x20,
++		[UART_LSR]	= 0x24,
++		[UART_MSR]	= 0x28,
++		[UART_SCR]	= 0x2c
++	},
++	regmap_out[8] = {
++		[UART_TX] 	= 0x04,
++		[UART_IER]	= 0x0c,
++		[UART_FCR]	= 0x18,
++		[UART_LCR]	= 0x1c,
++		[UART_MCR]	= 0x20,
++		[UART_LSR]	= 0x24,
++		[UART_MSR]	= 0x28,
++		[UART_SCR]	= 0x2c
++	};
++
++static inline int map_8250_in_reg(struct uart_port *p, int offset)
++{
++	if (p->iotype != UPIO_RM9000)
++		return offset;
++	return regmap_in[offset];
++}
++
++static inline int map_8250_out_reg(struct uart_port *p, int offset)
++{
++	if (p->iotype != UPIO_RM9000)
++		return offset;
++	return regmap_out[offset];
++}
++
++#else
++
++/* sane hardware needs no mapping */
++#define map_8250_in_reg(up, offset) (offset)
++#define map_8250_out_reg(up, offset) (offset)
++
++#endif
++
++static unsigned int hub6_serial_in(struct uart_port *p, int offset)
++{
++	offset = map_8250_in_reg(p, offset) << p->regshift;
++	outb(p->hub6 - 1 + offset, p->iobase);
++	return inb(p->iobase + 1);
++}
++
++static void hub6_serial_out(struct uart_port *p, int offset, int value)
++{
++	offset = map_8250_out_reg(p, offset) << p->regshift;
++	outb(p->hub6 - 1 + offset, p->iobase);
++	outb(value, p->iobase + 1);
++}
++
++static unsigned int mem_serial_in(struct uart_port *p, int offset)
++{
++	offset = map_8250_in_reg(p, offset) << p->regshift;
++	return readb(p->membase + offset);
++}
++
++static void mem_serial_out(struct uart_port *p, int offset, int value)
++{
++	offset = map_8250_out_reg(p, offset) << p->regshift;
++	writeb(value, p->membase + offset);
++}
++
++static void mem32_serial_out(struct uart_port *p, int offset, int value)
++{
++	offset = map_8250_out_reg(p, offset) << p->regshift;
++	writel(value, p->membase + offset);
++}
++
++static unsigned int mem32_serial_in(struct uart_port *p, int offset)
++{
++	offset = map_8250_in_reg(p, offset) << p->regshift;
++	return readl(p->membase + offset);
++}
++
++#ifdef CONFIG_SERIAL_8250_AU1X00
++static unsigned int au_serial_in(struct uart_port *p, int offset)
++{
++	offset = map_8250_in_reg(p, offset) << p->regshift;
++	return __raw_readl(p->membase + offset);
++}
++
++static void au_serial_out(struct uart_port *p, int offset, int value)
++{
++	offset = map_8250_out_reg(p, offset) << p->regshift;
++	__raw_writel(value, p->membase + offset);
++}
++#endif
++
++static unsigned int tsi_serial_in(struct uart_port *p, int offset)
++{
++	unsigned int tmp;
++	offset = map_8250_in_reg(p, offset) << p->regshift;
++	if (offset == UART_IIR) {
++		tmp = readl(p->membase + (UART_IIR & ~3));
++		return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
++	} else
++		return readb(p->membase + offset);
++}
++
++static void tsi_serial_out(struct uart_port *p, int offset, int value)
++{
++	offset = map_8250_out_reg(p, offset) << p->regshift;
++	if (!((offset == UART_IER) && (value & UART_IER_UUE)))
++		writeb(value, p->membase + offset);
++}
++
++static void dwapb_serial_out(struct uart_port *p, int offset, int value)
++{
++	int save_offset = offset;
++	offset = map_8250_out_reg(p, offset) << p->regshift;
++	/* Save the LCR value so it can be re-written when a
++	 * Busy Detect interrupt occurs. */
++	if (save_offset == UART_LCR) {
++		struct uart_8250_port *up = (struct uart_8250_port *)p;
++		up->lcr = value;
++	}
++	writeb(value, p->membase + offset);
++	/* Read the IER to ensure any interrupt is cleared before
++	 * returning from ISR. */
++	if (save_offset == UART_TX || save_offset == UART_IER)
++		value = p->serial_in(p, UART_IER);
++}
++
++static unsigned int io_serial_in(struct uart_port *p, int offset)
++{
++	offset = map_8250_in_reg(p, offset) << p->regshift;
++	return inb(p->iobase + offset);
++}
++
++static void io_serial_out(struct uart_port *p, int offset, int value)
++{
++	offset = map_8250_out_reg(p, offset) << p->regshift;
++	outb(value, p->iobase + offset);
++}
++
++static void set_io_from_upio(struct uart_port *p)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)p;
++	switch (p->iotype) {
++	case UPIO_HUB6:
++		p->serial_in = hub6_serial_in;
++		p->serial_out = hub6_serial_out;
++		break;
++
++	case UPIO_MEM:
++		p->serial_in = mem_serial_in;
++		p->serial_out = mem_serial_out;
++		break;
++
++	case UPIO_RM9000:
++	case UPIO_MEM32:
++		p->serial_in = mem32_serial_in;
++		p->serial_out = mem32_serial_out;
++		break;
++
++#ifdef CONFIG_SERIAL_8250_AU1X00
++	case UPIO_AU:
++		p->serial_in = au_serial_in;
++		p->serial_out = au_serial_out;
++		break;
++#endif
++	case UPIO_TSI:
++		p->serial_in = tsi_serial_in;
++		p->serial_out = tsi_serial_out;
++		break;
++
++	case UPIO_DWAPB:
++		p->serial_in = mem_serial_in;
++		p->serial_out = dwapb_serial_out;
++		break;
++
++	default:
++		p->serial_in = io_serial_in;
++		p->serial_out = io_serial_out;
++		break;
++	}
++	/* Remember loaded iotype */
++	up->cur_iotype = p->iotype;
++}
++
++static void
++serial_out_sync(struct uart_8250_port *up, int offset, int value)
++{
++	struct uart_port *p = &up->port;
++	switch (p->iotype) {
++	case UPIO_MEM:
++	case UPIO_MEM32:
++#ifdef CONFIG_SERIAL_8250_AU1X00
++	case UPIO_AU:
++#endif
++	case UPIO_DWAPB:
++		p->serial_out(p, offset, value);
++		p->serial_in(p, UART_LCR);	/* safe, no side-effects */
++		break;
++	default:
++		p->serial_out(p, offset, value);
++	}
++}
++
++#define serial_in(up, offset)		\
++	(up->port.serial_in(&(up)->port, (offset)))
++#define serial_out(up, offset, value)	\
++	(up->port.serial_out(&(up)->port, (offset), (value)))
++/*
++ * We used to support using pause I/O for certain machines.  We
++ * haven't supported this for a while, but just in case it's badly
++ * needed for certain old 386 machines, I've left these #define's
++ * in....
++ */
++#define serial_inp(up, offset)		serial_in(up, offset)
++#define serial_outp(up, offset, value)	serial_out(up, offset, value)
++
++/* Uart divisor latch read */
++static inline int _serial_dl_read(struct uart_8250_port *up)
++{
++	return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8;
++}
++
++/* Uart divisor latch write */
++static inline void _serial_dl_write(struct uart_8250_port *up, int value)
++{
++	serial_outp(up, UART_DLL, value & 0xff);
++	serial_outp(up, UART_DLM, value >> 8 & 0xff);
++}
++
++#if defined(CONFIG_SERIAL_8250_AU1X00)
++/* Au1x00 haven't got a standard divisor latch */
++static int serial_dl_read(struct uart_8250_port *up)
++{
++	if (up->port.iotype == UPIO_AU)
++		return __raw_readl(up->port.membase + 0x28);
++	else
++		return _serial_dl_read(up);
++}
++
++static void serial_dl_write(struct uart_8250_port *up, int value)
++{
++	if (up->port.iotype == UPIO_AU)
++		__raw_writel(value, up->port.membase + 0x28);
++	else
++		_serial_dl_write(up, value);
++}
++#elif defined(CONFIG_SERIAL_8250_RM9K)
++static int serial_dl_read(struct uart_8250_port *up)
++{
++	return	(up->port.iotype == UPIO_RM9000) ?
++		(((__raw_readl(up->port.membase + 0x10) << 8) |
++		(__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
++		_serial_dl_read(up);
++}
++
++static void serial_dl_write(struct uart_8250_port *up, int value)
++{
++	if (up->port.iotype == UPIO_RM9000) {
++		__raw_writel(value, up->port.membase + 0x08);
++		__raw_writel(value >> 8, up->port.membase + 0x10);
++	} else {
++		_serial_dl_write(up, value);
++	}
++}
++#else
++#define serial_dl_read(up) _serial_dl_read(up)
++#define serial_dl_write(up, value) _serial_dl_write(up, value)
++#endif
++
++/*
++ * For the 16C950
++ */
++static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
++{
++	serial_out(up, UART_SCR, offset);
++	serial_out(up, UART_ICR, value);
++}
++
++static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
++{
++	unsigned int value;
++
++	serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
++	serial_out(up, UART_SCR, offset);
++	value = serial_in(up, UART_ICR);
++	serial_icr_write(up, UART_ACR, up->acr);
++
++	return value;
++}
++
++/*
++ * FIFO support.
++ */
++static void serial8250_clear_fifos(struct uart_8250_port *p)
++{
++	if (p->capabilities & UART_CAP_FIFO) {
++		serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO);
++		serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO |
++			       UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
++		serial_outp(p, UART_FCR, 0);
++	}
++}
++
++/*
++ * IER sleep support.  UARTs which have EFRs need the "extended
++ * capability" bit enabled.  Note that on XR16C850s, we need to
++ * reset LCR to write to IER.
++ */
++static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
++{
++	if (p->capabilities & UART_CAP_SLEEP) {
++		if (p->capabilities & UART_CAP_EFR) {
++			serial_outp(p, UART_LCR, 0xBF);
++			serial_outp(p, UART_EFR, UART_EFR_ECB);
++			serial_outp(p, UART_LCR, 0);
++		}
++		serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
++		if (p->capabilities & UART_CAP_EFR) {
++			serial_outp(p, UART_LCR, 0xBF);
++			serial_outp(p, UART_EFR, 0);
++			serial_outp(p, UART_LCR, 0);
++		}
++	}
++}
++
++#ifdef CONFIG_SERIAL_8250_RSA
++/*
++ * Attempts to turn on the RSA FIFO.  Returns zero on failure.
++ * We set the port uart clock rate if we succeed.
++ */
++static int __enable_rsa(struct uart_8250_port *up)
++{
++	unsigned char mode;
++	int result;
++
++	mode = serial_inp(up, UART_RSA_MSR);
++	result = mode & UART_RSA_MSR_FIFO;
++
++	if (!result) {
++		serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
++		mode = serial_inp(up, UART_RSA_MSR);
++		result = mode & UART_RSA_MSR_FIFO;
++	}
++
++	if (result)
++		up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16;
++
++	return result;
++}
++
++static void enable_rsa(struct uart_8250_port *up)
++{
++	if (up->port.type == PORT_RSA) {
++		if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) {
++			spin_lock_irq(&up->port.lock);
++			__enable_rsa(up);
++			spin_unlock_irq(&up->port.lock);
++		}
++		if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
++			serial_outp(up, UART_RSA_FRR, 0);
++	}
++}
++
++/*
++ * Attempts to turn off the RSA FIFO.  Returns zero on failure.
++ * It is unknown why interrupts were disabled in here.  However,
++ * the caller is expected to preserve this behaviour by grabbing
++ * the spinlock before calling this function.
++ */
++static void disable_rsa(struct uart_8250_port *up)
++{
++	unsigned char mode;
++	int result;
++
++	if (up->port.type == PORT_RSA &&
++	    up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) {
++		spin_lock_irq(&up->port.lock);
++
++		mode = serial_inp(up, UART_RSA_MSR);
++		result = !(mode & UART_RSA_MSR_FIFO);
++
++		if (!result) {
++			serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
++			mode = serial_inp(up, UART_RSA_MSR);
++			result = !(mode & UART_RSA_MSR_FIFO);
++		}
++
++		if (result)
++			up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16;
++		spin_unlock_irq(&up->port.lock);
++	}
++}
++#endif /* CONFIG_SERIAL_8250_RSA */
++
++/*
++ * This is a quickie test to see how big the FIFO is.
++ * It doesn't work at all the time, more's the pity.
++ */
++static int size_fifo(struct uart_8250_port *up)
++{
++	unsigned char old_fcr, old_mcr, old_lcr;
++	unsigned short old_dl;
++	int count;
++
++	old_lcr = serial_inp(up, UART_LCR);
++	serial_outp(up, UART_LCR, 0);
++	old_fcr = serial_inp(up, UART_FCR);
++	old_mcr = serial_inp(up, UART_MCR);
++	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
++		    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
++	serial_outp(up, UART_MCR, UART_MCR_LOOP);
++	serial_outp(up, UART_LCR, UART_LCR_DLAB);
++	old_dl = serial_dl_read(up);
++	serial_dl_write(up, 0x0001);
++	serial_outp(up, UART_LCR, 0x03);
++	for (count = 0; count < 256; count++)
++		serial_outp(up, UART_TX, count);
++	mdelay(20);/* FIXME - schedule_timeout */
++	for (count = 0; (serial_inp(up, UART_LSR) & UART_LSR_DR) &&
++	     (count < 256); count++)
++		serial_inp(up, UART_RX);
++	serial_outp(up, UART_FCR, old_fcr);
++	serial_outp(up, UART_MCR, old_mcr);
++	serial_outp(up, UART_LCR, UART_LCR_DLAB);
++	serial_dl_write(up, old_dl);
++	serial_outp(up, UART_LCR, old_lcr);
++
++	return count;
++}
++
++/*
++ * Read UART ID using the divisor method - set DLL and DLM to zero
++ * and the revision will be in DLL and device type in DLM.  We
++ * preserve the device state across this.
++ */
++static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
++{
++	unsigned char old_dll, old_dlm, old_lcr;
++	unsigned int id;
++
++	old_lcr = serial_inp(p, UART_LCR);
++	serial_outp(p, UART_LCR, UART_LCR_DLAB);
++
++	old_dll = serial_inp(p, UART_DLL);
++	old_dlm = serial_inp(p, UART_DLM);
++
++	serial_outp(p, UART_DLL, 0);
++	serial_outp(p, UART_DLM, 0);
++
++	id = serial_inp(p, UART_DLL) | serial_inp(p, UART_DLM) << 8;
++
++	serial_outp(p, UART_DLL, old_dll);
++	serial_outp(p, UART_DLM, old_dlm);
++	serial_outp(p, UART_LCR, old_lcr);
++
++	return id;
++}
++
++/*
++ * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
++ * When this function is called we know it is at least a StarTech
++ * 16650 V2, but it might be one of several StarTech UARTs, or one of
++ * its clones.  (We treat the broken original StarTech 16650 V1 as a
++ * 16550, and why not?  Startech doesn't seem to even acknowledge its
++ * existence.)
++ *
++ * What evil have men's minds wrought...
++ */
++static void autoconfig_has_efr(struct uart_8250_port *up)
++{
++	unsigned int id1, id2, id3, rev;
++
++	/*
++	 * Everything with an EFR has SLEEP
++	 */
++	up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
++
++	/*
++	 * First we check to see if it's an Oxford Semiconductor UART.
++	 *
++	 * If we have to do this here because some non-National
++	 * Semiconductor clone chips lock up if you try writing to the
++	 * LSR register (which serial_icr_read does)
++	 */
++
++	/*
++	 * Check for Oxford Semiconductor 16C950.
++	 *
++	 * EFR [4] must be set else this test fails.
++	 *
++	 * This shouldn't be necessary, but Mike Hudson (Exoray at 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 at 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 at 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 at 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 at 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 at cc.hut.fi> and
++   Frodo Looijaard <frodol at 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. at 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 at 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 at linutronix.de>
++ *  Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar
++ *  Copyright(C) 2006-2007  Timesys Corp., Thomas Gleixner
++ *
++ *  High-resolution kernel timers
++ *
++ *  In contrast to the low-resolution timeout API implemented in
++ *  kernel/timer.c, hrtimers provide finer resolution and accuracy
++ *  depending on system configuration and capabilities.
++ *
++ *  These timers are currently used for:
++ *   - itimers
++ *   - POSIX timers
++ *   - nanosleep
++ *   - precise in-kernel timing
++ *
++ *  Started by: Thomas Gleixner and Ingo Molnar
++ *
++ *  Credits:
++ *	based on kernel/timer.c
++ *
++ *	Help, testing, suggestions, bugfixes, improvements were
++ *	provided by:
++ *
++ *	George Anzinger, Andrew Morton, Steven Rostedt, Roman Zippel
++ *	et. al.
++ *
++ *  For licencing details see kernel-base/COPYING
++ */
++
++#include <linux/cpu.h>
++#include <linux/module.h>
++#include <linux/percpu.h>
++#include <linux/hrtimer.h>
++#include <linux/notifier.h>
++#include <linux/syscalls.h>
++#include <linux/kallsyms.h>
++#include <linux/interrupt.h>
++#include <linux/tick.h>
++#include <linux/seq_file.h>
++#include <linux/err.h>
++#include <linux/debugobjects.h>
++#include <linux/sched.h>
++#include <linux/timer.h>
++
++#include <asm/uaccess.h>
++
++#include <trace/events/timer.h>
++
++/*
++ * The timer bases:
++ *
++ * Note: If we want to add new timer bases, we have to skip the two
++ * clock ids captured by the cpu-timers. We do this by holding empty
++ * entries rather than doing math adjustment of the clock ids.
++ * This ensures that we capture erroneous accesses to these clock ids
++ * rather than moving them into the range of valid clock id's.
++ */
++DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
++{
++
++	.clock_base =
++	{
++		{
++			.index = CLOCK_REALTIME,
++			.get_time = &ktime_get_real,
++			.resolution = KTIME_LOW_RES,
++		},
++		{
++			.index = CLOCK_MONOTONIC,
++			.get_time = &ktime_get,
++			.resolution = KTIME_LOW_RES,
++		},
++	}
++};
++
++/*
++ * Get the coarse grained time at the softirq based on xtime and
++ * wall_to_monotonic.
++ */
++static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)
++{
++	ktime_t xtim, tomono;
++	struct timespec xts, tom;
++	unsigned long seq;
++
++	do {
++		seq = read_seqbegin(&xtime_lock);
++		xts = __current_kernel_time();
++		tom = wall_to_monotonic;
++	} while (read_seqretry(&xtime_lock, seq));
++
++	xtim = timespec_to_ktime(xts);
++	tomono = timespec_to_ktime(tom);
++	base->clock_base[CLOCK_REALTIME].softirq_time = xtim;
++	base->clock_base[CLOCK_MONOTONIC].softirq_time =
++		ktime_add(xtim, tomono);
++}
++
++/*
++ * Functions and macros which are different for UP/SMP systems are kept in a
++ * single place
++ */
++#ifdef CONFIG_SMP
++
++/*
++ * We are using hashed locking: holding per_cpu(hrtimer_bases)[n].lock
++ * means that all timers which are tied to this base via timer->base are
++ * locked, and the base itself is locked too.
++ *
++ * So __run_timers/migrate_timers can safely modify all timers which could
++ * be found on the lists/queues.
++ *
++ * When the timer's base is locked, and the timer removed from list, it is
++ * possible to set timer->base = NULL and drop the lock: the timer remains
++ * locked.
++ */
++static
++struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer,
++					     unsigned long *flags)
++{
++	struct hrtimer_clock_base *base;
++
++	for (;;) {
++		base = timer->base;
++		if (likely(base != NULL)) {
++			raw_spin_lock_irqsave(&base->cpu_base->lock, *flags);
++			if (likely(base == timer->base))
++				return base;
++			/* The timer has migrated to another CPU: */
++			raw_spin_unlock_irqrestore(&base->cpu_base->lock, *flags);
++		}
++		cpu_relax();
++	}
++}
++
++
++/*
++ * Get the preferred target CPU for NOHZ
++ */
++static int hrtimer_get_target(int this_cpu, int pinned)
++{
++#ifdef CONFIG_NO_HZ
++	if (!pinned && get_sysctl_timer_migration() && idle_cpu(this_cpu)) {
++		int preferred_cpu = get_nohz_load_balancer();
++
++		if (preferred_cpu >= 0)
++			return preferred_cpu;
++	}
++#endif
++	return this_cpu;
++}
++
++/*
++ * With HIGHRES=y we do not migrate the timer when it is expiring
++ * before the next event on the target cpu because we cannot reprogram
++ * the target cpu hardware and we would cause it to fire late.
++ *
++ * Called with cpu_base->lock of target cpu held.
++ */
++static int
++hrtimer_check_target(struct hrtimer *timer, struct hrtimer_clock_base *new_base)
++{
++#ifdef CONFIG_HIGH_RES_TIMERS
++	ktime_t expires;
++
++	if (!new_base->cpu_base->hres_active)
++		return 0;
++
++	expires = ktime_sub(hrtimer_get_expires(timer), new_base->offset);
++	return expires.tv64 <= new_base->cpu_base->expires_next.tv64;
++#else
++	return 0;
++#endif
++}
++
++/*
++ * Switch the timer base to the current CPU when possible.
++ */
++static inline struct hrtimer_clock_base *
++switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base,
++		    int pinned)
++{
++	struct hrtimer_clock_base *new_base;
++	struct hrtimer_cpu_base *new_cpu_base;
++	int this_cpu = smp_processor_id();
++	int cpu = hrtimer_get_target(this_cpu, pinned);
++
++again:
++	new_cpu_base = &per_cpu(hrtimer_bases, cpu);
++	new_base = &new_cpu_base->clock_base[base->index];
++
++	if (base != new_base) {
++		/*
++		 * We are trying to move timer to new_base.
++		 * However we can't change timer's base while it is running,
++		 * so we keep it on the same CPU. No hassle vs. reprogramming
++		 * the event source in the high resolution case. The softirq
++		 * code will take care of this when the timer function has
++		 * completed. There is no conflict as we hold the lock until
++		 * the timer is enqueued.
++		 */
++		if (unlikely(hrtimer_callback_running(timer)))
++			return base;
++
++		/* See the comment in lock_timer_base() */
++		timer->base = NULL;
++		raw_spin_unlock(&base->cpu_base->lock);
++		raw_spin_lock(&new_base->cpu_base->lock);
++
++		if (cpu != this_cpu && hrtimer_check_target(timer, new_base)) {
++			cpu = this_cpu;
++			raw_spin_unlock(&new_base->cpu_base->lock);
++			raw_spin_lock(&base->cpu_base->lock);
++			timer->base = base;
++			goto again;
++		}
++		timer->base = new_base;
++	}
++	return new_base;
++}
++
++#else /* CONFIG_SMP */
++
++static inline struct hrtimer_clock_base *
++lock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
++{
++	struct hrtimer_clock_base *base = timer->base;
++
++	raw_spin_lock_irqsave(&base->cpu_base->lock, *flags);
++
++	return base;
++}
++
++# define switch_hrtimer_base(t, b, p)	(b)
++
++#endif	/* !CONFIG_SMP */
++
++/*
++ * Functions for the union type storage format of ktime_t which are
++ * too large for inlining:
++ */
++#if BITS_PER_LONG < 64
++# ifndef CONFIG_KTIME_SCALAR
++/**
++ * ktime_add_ns - Add a scalar nanoseconds value to a ktime_t variable
++ * @kt:		addend
++ * @nsec:	the scalar nsec value to add
++ *
++ * Returns the sum of kt and nsec in ktime_t format
++ */
++ktime_t ktime_add_ns(const ktime_t kt, u64 nsec)
++{
++	ktime_t tmp;
++
++	if (likely(nsec < NSEC_PER_SEC)) {
++		tmp.tv64 = nsec;
++	} else {
++		unsigned long rem = do_div(nsec, NSEC_PER_SEC);
++
++		tmp = ktime_set((long)nsec, rem);
++	}
++
++	return ktime_add(kt, tmp);
++}
++
++EXPORT_SYMBOL_GPL(ktime_add_ns);
++
++/**
++ * ktime_sub_ns - Subtract a scalar nanoseconds value from a ktime_t variable
++ * @kt:		minuend
++ * @nsec:	the scalar nsec value to subtract
++ *
++ * Returns the subtraction of @nsec from @kt in ktime_t format
++ */
++ktime_t ktime_sub_ns(const ktime_t kt, u64 nsec)
++{
++	ktime_t tmp;
++
++	if (likely(nsec < NSEC_PER_SEC)) {
++		tmp.tv64 = nsec;
++	} else {
++		unsigned long rem = do_div(nsec, NSEC_PER_SEC);
++
++		tmp = ktime_set((long)nsec, rem);
++	}
++
++	return ktime_sub(kt, tmp);
++}
++
++EXPORT_SYMBOL_GPL(ktime_sub_ns);
++# endif /* !CONFIG_KTIME_SCALAR */
++
++/*
++ * Divide a ktime value by a nanosecond value
++ */
++u64 ktime_divns(const ktime_t kt, s64 div)
++{
++	u64 dclc;
++	int sft = 0;
++
++	dclc = ktime_to_ns(kt);
++	/* Make sure the divisor is less than 2^32: */
++	while (div >> 32) {
++		sft++;
++		div >>= 1;
++	}
++	dclc >>= sft;
++	do_div(dclc, (unsigned long) div);
++
++	return dclc;
++}
++#endif /* BITS_PER_LONG >= 64 */
++
++/*
++ * Add two ktime values and do a safety check for overflow:
++ */
++ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs)
++{
++	ktime_t res = ktime_add(lhs, rhs);
++
++	/*
++	 * We use KTIME_SEC_MAX here, the maximum timeout which we can
++	 * return to user space in a timespec:
++	 */
++	if (res.tv64 < 0 || res.tv64 < lhs.tv64 || res.tv64 < rhs.tv64)
++		res = ktime_set(KTIME_SEC_MAX, 0);
++
++	return res;
++}
++
++EXPORT_SYMBOL_GPL(ktime_add_safe);
++
++#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
++
++static struct debug_obj_descr hrtimer_debug_descr;
++
++/*
++ * fixup_init is called when:
++ * - an active object is initialized
++ */
++static int hrtimer_fixup_init(void *addr, enum debug_obj_state state)
++{
++	struct hrtimer *timer = addr;
++
++	switch (state) {
++	case ODEBUG_STATE_ACTIVE:
++		hrtimer_cancel(timer);
++		debug_object_init(timer, &hrtimer_debug_descr);
++		return 1;
++	default:
++		return 0;
++	}
++}
++
++/*
++ * fixup_activate is called when:
++ * - an active object is activated
++ * - an unknown object is activated (might be a statically initialized object)
++ */
++static int hrtimer_fixup_activate(void *addr, enum debug_obj_state state)
++{
++	switch (state) {
++
++	case ODEBUG_STATE_NOTAVAILABLE:
++		WARN_ON_ONCE(1);
++		return 0;
++
++	case ODEBUG_STATE_ACTIVE:
++		WARN_ON(1);
++
++	default:
++		return 0;
++	}
++}
++
++/*
++ * fixup_free is called when:
++ * - an active object is freed
++ */
++static int hrtimer_fixup_free(void *addr, enum debug_obj_state state)
++{
++	struct hrtimer *timer = addr;
++
++	switch (state) {
++	case ODEBUG_STATE_ACTIVE:
++		hrtimer_cancel(timer);
++		debug_object_free(timer, &hrtimer_debug_descr);
++		return 1;
++	default:
++		return 0;
++	}
++}
++
++static struct debug_obj_descr hrtimer_debug_descr = {
++	.name		= "hrtimer",
++	.fixup_init	= hrtimer_fixup_init,
++	.fixup_activate	= hrtimer_fixup_activate,
++	.fixup_free	= hrtimer_fixup_free,
++};
++
++static inline void debug_hrtimer_init(struct hrtimer *timer)
++{
++	debug_object_init(timer, &hrtimer_debug_descr);
++}
++
++static inline void debug_hrtimer_activate(struct hrtimer *timer)
++{
++	debug_object_activate(timer, &hrtimer_debug_descr);
++}
++
++static inline void debug_hrtimer_deactivate(struct hrtimer *timer)
++{
++	debug_object_deactivate(timer, &hrtimer_debug_descr);
++}
++
++static inline void debug_hrtimer_free(struct hrtimer *timer)
++{
++	debug_object_free(timer, &hrtimer_debug_descr);
++}
++
++static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
++			   enum hrtimer_mode mode);
++
++void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t clock_id,
++			   enum hrtimer_mode mode)
++{
++	debug_object_init_on_stack(timer, &hrtimer_debug_descr);
++	__hrtimer_init(timer, clock_id, mode);
++}
++EXPORT_SYMBOL_GPL(hrtimer_init_on_stack);
++
++void destroy_hrtimer_on_stack(struct hrtimer *timer)
++{
++	debug_object_free(timer, &hrtimer_debug_descr);
++}
++
++#else
++static inline void debug_hrtimer_init(struct hrtimer *timer) { }
++static inline void debug_hrtimer_activate(struct hrtimer *timer) { }
++static inline void debug_hrtimer_deactivate(struct hrtimer *timer) { }
++#endif
++
++static inline void
++debug_init(struct hrtimer *timer, clockid_t clockid,
++	   enum hrtimer_mode mode)
++{
++	debug_hrtimer_init(timer);
++	trace_hrtimer_init(timer, clockid, mode);
++}
++
++static inline void debug_activate(struct hrtimer *timer)
++{
++	debug_hrtimer_activate(timer);
++	trace_hrtimer_start(timer);
++}
++
++static inline void debug_deactivate(struct hrtimer *timer)
++{
++	debug_hrtimer_deactivate(timer);
++	trace_hrtimer_cancel(timer);
++}
++
++/* High resolution timer related functions */
++#ifdef CONFIG_HIGH_RES_TIMERS
++
++/*
++ * High resolution timer enabled ?
++ */
++static int hrtimer_hres_enabled __read_mostly  = 1;
++
++/*
++ * Enable / Disable high resolution mode
++ */
++static int __init setup_hrtimer_hres(char *str)
++{
++	if (!strcmp(str, "off"))
++		hrtimer_hres_enabled = 0;
++	else if (!strcmp(str, "on"))
++		hrtimer_hres_enabled = 1;
++	else
++		return 0;
++	return 1;
++}
++
++__setup("highres=", setup_hrtimer_hres);
++
++/*
++ * hrtimer_high_res_enabled - query, if the highres mode is enabled
++ */
++static inline int hrtimer_is_hres_enabled(void)
++{
++	return hrtimer_hres_enabled;
++}
++
++/*
++ * Is the high resolution mode active ?
++ */
++static inline int hrtimer_hres_active(void)
++{
++	return __get_cpu_var(hrtimer_bases).hres_active;
++}
++
++/*
++ * Reprogram the event source with checking both queues for the
++ * next event
++ * Called with interrupts disabled and base->lock held
++ */
++static void
++hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal)
++{
++	int i;
++	struct hrtimer_clock_base *base = cpu_base->clock_base;
++	ktime_t expires, expires_next;
++
++	expires_next.tv64 = KTIME_MAX;
++
++	for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) {
++		struct hrtimer *timer;
++
++		if (!base->first)
++			continue;
++		timer = rb_entry(base->first, struct hrtimer, node);
++		expires = ktime_sub(hrtimer_get_expires(timer), base->offset);
++		/*
++		 * clock_was_set() has changed base->offset so the
++		 * result might be negative. Fix it up to prevent a
++		 * false positive in clockevents_program_event()
++		 */
++		if (expires.tv64 < 0)
++			expires.tv64 = 0;
++		if (expires.tv64 < expires_next.tv64)
++			expires_next = expires;
++	}
++
++	if (skip_equal && expires_next.tv64 == cpu_base->expires_next.tv64)
++		return;
++
++	cpu_base->expires_next.tv64 = expires_next.tv64;
++
++	if (cpu_base->expires_next.tv64 != KTIME_MAX)
++		tick_program_event(cpu_base->expires_next, 1);
++}
++
++/*
++ * Shared reprogramming for clock_realtime and clock_monotonic
++ *
++ * When a timer is enqueued and expires earlier than the already enqueued
++ * timers, we have to check, whether it expires earlier than the timer for
++ * which the clock event device was armed.
++ *
++ * Called with interrupts disabled and base->cpu_base.lock held
++ */
++static int hrtimer_reprogram(struct hrtimer *timer,
++			     struct hrtimer_clock_base *base)
++{
++	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
++	ktime_t expires = ktime_sub(hrtimer_get_expires(timer), base->offset);
++	int res;
++
++	WARN_ON_ONCE(hrtimer_get_expires_tv64(timer) < 0);
++
++	/*
++	 * When the callback is running, we do not reprogram the clock event
++	 * device. The timer callback is either running on a different CPU or
++	 * the callback is executed in the hrtimer_interrupt context. The
++	 * reprogramming is handled either by the softirq, which called the
++	 * callback or at the end of the hrtimer_interrupt.
++	 */
++	if (hrtimer_callback_running(timer))
++		return 0;
++
++	/*
++	 * CLOCK_REALTIME timer might be requested with an absolute
++	 * expiry time which is less than base->offset. Nothing wrong
++	 * about that, just avoid to call into the tick code, which
++	 * has now objections against negative expiry values.
++	 */
++	if (expires.tv64 < 0)
++		return -ETIME;
++
++	if (expires.tv64 >= cpu_base->expires_next.tv64)
++		return 0;
++
++	/*
++	 * If a hang was detected in the last timer interrupt then we
++	 * do not schedule a timer which is earlier than the expiry
++	 * which we enforced in the hang detection. We want the system
++	 * to make progress.
++	 */
++	if (cpu_base->hang_detected)
++		return 0;
++
++	/*
++	 * Clockevents returns -ETIME, when the event was in the past.
++	 */
++	res = tick_program_event(expires, 0);
++	if (!IS_ERR_VALUE(res))
++		cpu_base->expires_next = expires;
++	return res;
++}
++
++
++/*
++ * Retrigger next event is called after clock was set
++ *
++ * Called with interrupts disabled via on_each_cpu()
++ */
++static void retrigger_next_event(void *arg)
++{
++	struct hrtimer_cpu_base *base;
++	struct timespec realtime_offset;
++	unsigned long seq;
++
++	if (!hrtimer_hres_active())
++		return;
++
++	do {
++		seq = read_seqbegin(&xtime_lock);
++		set_normalized_timespec(&realtime_offset,
++					-wall_to_monotonic.tv_sec,
++					-wall_to_monotonic.tv_nsec);
++	} while (read_seqretry(&xtime_lock, seq));
++
++	base = &__get_cpu_var(hrtimer_bases);
++
++	/* Adjust CLOCK_REALTIME offset */
++	raw_spin_lock(&base->lock);
++	base->clock_base[CLOCK_REALTIME].offset =
++		timespec_to_ktime(realtime_offset);
++
++	hrtimer_force_reprogram(base, 0);
++	raw_spin_unlock(&base->lock);
++}
++
++/*
++ * Clock realtime was set
++ *
++ * Change the offset of the realtime clock vs. the monotonic
++ * clock.
++ *
++ * We might have to reprogram the high resolution timer interrupt. On
++ * SMP we call the architecture specific code to retrigger _all_ high
++ * resolution timer interrupts. On UP we just disable interrupts and
++ * call the high resolution interrupt code.
++ */
++void clock_was_set(void)
++{
++	/* Retrigger the CPU local events everywhere */
++	on_each_cpu(retrigger_next_event, NULL, 1);
++}
++
++/*
++ * During resume we might have to reprogram the high resolution timer
++ * interrupt (on the local CPU):
++ */
++void hres_timers_resume(void)
++{
++	WARN_ONCE(!irqs_disabled(),
++		  KERN_INFO "hres_timers_resume() called with IRQs enabled!");
++
++	retrigger_next_event(NULL);
++}
++
++/*
++ * Initialize the high resolution related parts of cpu_base
++ */
++static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base)
++{
++	base->expires_next.tv64 = KTIME_MAX;
++	base->hres_active = 0;
++}
++
++/*
++ * Initialize the high resolution related parts of a hrtimer
++ */
++static inline void hrtimer_init_timer_hres(struct hrtimer *timer)
++{
++}
++
++
++/*
++ * When High resolution timers are active, try to reprogram. Note, that in case
++ * the state has HRTIMER_STATE_CALLBACK set, no reprogramming and no expiry
++ * check happens. The timer gets enqueued into the rbtree. The reprogramming
++ * and expiry check is done in the hrtimer_interrupt or in the softirq.
++ */
++static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
++					    struct hrtimer_clock_base *base,
++					    int wakeup)
++{
++	if (base->cpu_base->hres_active && hrtimer_reprogram(timer, base)) {
++		if (wakeup) {
++			raw_spin_unlock(&base->cpu_base->lock);
++			raise_softirq_irqoff(HRTIMER_SOFTIRQ);
++			raw_spin_lock(&base->cpu_base->lock);
++		} else
++			__raise_softirq_irqoff(HRTIMER_SOFTIRQ);
++
++		return 1;
++	}
++
++	return 0;
++}
++
++/*
++ * Switch to high resolution mode
++ */
++static int hrtimer_switch_to_hres(void)
++{
++	int cpu = smp_processor_id();
++	struct hrtimer_cpu_base *base = &per_cpu(hrtimer_bases, cpu);
++	unsigned long flags;
++
++	if (base->hres_active)
++		return 1;
++
++	local_irq_save(flags);
++
++	if (tick_init_highres()) {
++		local_irq_restore(flags);
++		printk(KERN_WARNING "Could not switch to high resolution "
++				    "mode on CPU %d\n", cpu);
++		return 0;
++	}
++	base->hres_active = 1;
++	base->clock_base[CLOCK_REALTIME].resolution = KTIME_HIGH_RES;
++	base->clock_base[CLOCK_MONOTONIC].resolution = KTIME_HIGH_RES;
++
++	tick_setup_sched_timer();
++
++	/* "Retrigger" the interrupt to get things going */
++	retrigger_next_event(NULL);
++	local_irq_restore(flags);
++	return 1;
++}
++
++#else
++
++static inline int hrtimer_hres_active(void) { return 0; }
++static inline int hrtimer_is_hres_enabled(void) { return 0; }
++static inline int hrtimer_switch_to_hres(void) { return 0; }
++static inline void
++hrtimer_force_reprogram(struct hrtimer_cpu_base *base, int skip_equal) { }
++static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
++					    struct hrtimer_clock_base *base,
++					    int wakeup)
++{
++	return 0;
++}
++static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) { }
++static inline void hrtimer_init_timer_hres(struct hrtimer *timer) { }
++
++#endif /* CONFIG_HIGH_RES_TIMERS */
++
++static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer)
++{
++#ifdef CONFIG_TIMER_STATS
++	if (timer->start_site)
++		return;
++	timer->start_site = __builtin_return_address(0);
++	memcpy(timer->start_comm, current->comm, TASK_COMM_LEN);
++	timer->start_pid = current->pid;
++#endif
++}
++
++static inline void timer_stats_hrtimer_clear_start_info(struct hrtimer *timer)
++{
++#ifdef CONFIG_TIMER_STATS
++	timer->start_site = NULL;
++#endif
++}
++
++static inline void timer_stats_account_hrtimer(struct hrtimer *timer)
++{
++#ifdef CONFIG_TIMER_STATS
++	if (likely(!timer_stats_active))
++		return;
++	timer_stats_update_stats(timer, timer->start_pid, timer->start_site,
++				 timer->function, timer->start_comm, 0);
++#endif
++}
++
++/*
++ * Counterpart to lock_hrtimer_base above:
++ */
++static inline
++void unlock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
++{
++	raw_spin_unlock_irqrestore(&timer->base->cpu_base->lock, *flags);
++}
++
++/**
++ * hrtimer_forward - forward the timer expiry
++ * @timer:	hrtimer to forward
++ * @now:	forward past this time
++ * @interval:	the interval to forward
++ *
++ * Forward the timer expiry so it will expire in the future.
++ * Returns the number of overruns.
++ */
++u64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval)
++{
++	u64 orun = 1;
++	ktime_t delta;
++
++	delta = ktime_sub(now, hrtimer_get_expires(timer));
++
++	if (delta.tv64 < 0)
++		return 0;
++
++	if (interval.tv64 < timer->base->resolution.tv64)
++		interval.tv64 = timer->base->resolution.tv64;
++
++	if (unlikely(delta.tv64 >= interval.tv64)) {
++		s64 incr = ktime_to_ns(interval);
++
++		orun = ktime_divns(delta, incr);
++		hrtimer_add_expires_ns(timer, incr * orun);
++		if (hrtimer_get_expires_tv64(timer) > now.tv64)
++			return orun;
++		/*
++		 * This (and the ktime_add() below) is the
++		 * correction for exact:
++		 */
++		orun++;
++	}
++	hrtimer_add_expires(timer, interval);
++
++	return orun;
++}
++EXPORT_SYMBOL_GPL(hrtimer_forward);
++
++/*
++ * enqueue_hrtimer - internal function to (re)start a timer
++ *
++ * The timer is inserted in expiry order. Insertion into the
++ * red black tree is O(log(n)). Must hold the base lock.
++ *
++ * Returns 1 when the new timer is the leftmost timer in the tree.
++ */
++static int enqueue_hrtimer(struct hrtimer *timer,
++			   struct hrtimer_clock_base *base)
++{
++	struct rb_node **link = &base->active.rb_node;
++	struct rb_node *parent = NULL;
++	struct hrtimer *entry;
++	int leftmost = 1;
++
++	debug_activate(timer);
++
++	/*
++	 * Find the right place in the rbtree:
++	 */
++	while (*link) {
++		parent = *link;
++		entry = rb_entry(parent, struct hrtimer, node);
++		/*
++		 * We dont care about collisions. Nodes with
++		 * the same expiry time stay together.
++		 */
++		if (hrtimer_get_expires_tv64(timer) <
++				hrtimer_get_expires_tv64(entry)) {
++			link = &(*link)->rb_left;
++		} else {
++			link = &(*link)->rb_right;
++			leftmost = 0;
++		}
++	}
++
++	/*
++	 * Insert the timer to the rbtree and check whether it
++	 * replaces the first pending timer
++	 */
++	if (leftmost)
++		base->first = &timer->node;
++
++	rb_link_node(&timer->node, parent, link);
++	rb_insert_color(&timer->node, &base->active);
++	/*
++	 * HRTIMER_STATE_ENQUEUED is or'ed to the current state to preserve the
++	 * state of a possibly running callback.
++	 */
++	timer->state |= HRTIMER_STATE_ENQUEUED;
++
++	return leftmost;
++}
++
++/*
++ * __remove_hrtimer - internal function to remove a timer
++ *
++ * Caller must hold the base lock.
++ *
++ * High resolution timer mode reprograms the clock event device when the
++ * timer is the one which expires next. The caller can disable this by setting
++ * reprogram to zero. This is useful, when the context does a reprogramming
++ * anyway (e.g. timer interrupt)
++ */
++static void __remove_hrtimer(struct hrtimer *timer,
++			     struct hrtimer_clock_base *base,
++			     unsigned long newstate, int reprogram)
++{
++	if (!(timer->state & HRTIMER_STATE_ENQUEUED))
++		goto out;
++
++	/*
++	 * Remove the timer from the rbtree and replace the first
++	 * entry pointer if necessary.
++	 */
++	if (base->first == &timer->node) {
++		base->first = rb_next(&timer->node);
++#ifdef CONFIG_HIGH_RES_TIMERS
++		/* Reprogram the clock event device. if enabled */
++		if (reprogram && hrtimer_hres_active()) {
++			ktime_t expires;
++
++			expires = ktime_sub(hrtimer_get_expires(timer),
++					    base->offset);
++			if (base->cpu_base->expires_next.tv64 == expires.tv64)
++				hrtimer_force_reprogram(base->cpu_base, 1);
++		}
++#endif
++	}
++	rb_erase(&timer->node, &base->active);
++out:
++	timer->state = newstate;
++}
++
++/*
++ * remove hrtimer, called with base lock held
++ */
++static inline int
++remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base)
++{
++	if (hrtimer_is_queued(timer)) {
++		unsigned long state;
++		int reprogram;
++
++		/*
++		 * Remove the timer and force reprogramming when high
++		 * resolution mode is active and the timer is on the current
++		 * CPU. If we remove a timer on another CPU, reprogramming is
++		 * skipped. The interrupt event on this CPU is fired and
++		 * reprogramming happens in the interrupt handler. This is a
++		 * rare case and less expensive than a smp call.
++		 */
++		debug_deactivate(timer);
++		timer_stats_hrtimer_clear_start_info(timer);
++		reprogram = base->cpu_base == &__get_cpu_var(hrtimer_bases);
++		/*
++		 * We must preserve the CALLBACK state flag here,
++		 * otherwise we could move the timer base in
++		 * switch_hrtimer_base.
++		 */
++		state = timer->state & HRTIMER_STATE_CALLBACK;
++		__remove_hrtimer(timer, base, state, reprogram);
++		return 1;
++	}
++	return 0;
++}
++
++int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
++		unsigned long delta_ns, const enum hrtimer_mode mode,
++		int wakeup)
++{
++	struct hrtimer_clock_base *base, *new_base;
++	unsigned long flags;
++	int ret, leftmost;
++
++	base = lock_hrtimer_base(timer, &flags);
++
++	/* Remove an active timer from the queue: */
++	ret = remove_hrtimer(timer, base);
++
++	/* Switch the timer base, if necessary: */
++	new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
++
++	if (mode & HRTIMER_MODE_REL) {
++		tim = ktime_add_safe(tim, new_base->get_time());
++		/*
++		 * CONFIG_TIME_LOW_RES is a temporary way for architectures
++		 * to signal that they simply return xtime in
++		 * do_gettimeoffset(). In this case we want to round up by
++		 * resolution when starting a relative timer, to avoid short
++		 * timeouts. This will go away with the GTOD framework.
++		 */
++#ifdef CONFIG_TIME_LOW_RES
++		tim = ktime_add_safe(tim, base->resolution);
++#endif
++	}
++
++	hrtimer_set_expires_range_ns(timer, tim, delta_ns);
++
++	timer_stats_hrtimer_set_start_info(timer);
++
++	leftmost = enqueue_hrtimer(timer, new_base);
++
++	/*
++	 * Only allow reprogramming if the new base is on this CPU.
++	 * (it might still be on another CPU if the timer was pending)
++	 *
++	 * XXX send_remote_softirq() ?
++	 */
++	if (leftmost && new_base->cpu_base == &__get_cpu_var(hrtimer_bases))
++		hrtimer_enqueue_reprogram(timer, new_base, wakeup);
++
++	unlock_hrtimer_base(timer, &flags);
++
++	return ret;
++}
++
++/**
++ * hrtimer_start_range_ns - (re)start an hrtimer on the current CPU
++ * @timer:	the timer to be added
++ * @tim:	expiry time
++ * @delta_ns:	"slack" range for the timer
++ * @mode:	expiry mode: absolute (HRTIMER_ABS) or relative (HRTIMER_REL)
++ *
++ * Returns:
++ *  0 on success
++ *  1 when the timer was active
++ */
++int hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
++		unsigned long delta_ns, const enum hrtimer_mode mode)
++{
++	return __hrtimer_start_range_ns(timer, tim, delta_ns, mode, 1);
++}
++EXPORT_SYMBOL_GPL(hrtimer_start_range_ns);
++
++/**
++ * hrtimer_start - (re)start an hrtimer on the current CPU
++ * @timer:	the timer to be added
++ * @tim:	expiry time
++ * @mode:	expiry mode: absolute (HRTIMER_ABS) or relative (HRTIMER_REL)
++ *
++ * Returns:
++ *  0 on success
++ *  1 when the timer was active
++ */
++int
++hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
++{
++	return __hrtimer_start_range_ns(timer, tim, 0, mode, 1);
++}
++EXPORT_SYMBOL_GPL(hrtimer_start);
++
++
++/**
++ * hrtimer_try_to_cancel - try to deactivate a timer
++ * @timer:	hrtimer to stop
++ *
++ * Returns:
++ *  0 when the timer was not active
++ *  1 when the timer was active
++ * -1 when the timer is currently excuting the callback function and
++ *    cannot be stopped
++ */
++int hrtimer_try_to_cancel(struct hrtimer *timer)
++{
++	struct hrtimer_clock_base *base;
++	unsigned long flags;
++	int ret = -1;
++
++	base = lock_hrtimer_base(timer, &flags);
++
++	if (!hrtimer_callback_running(timer))
++		ret = remove_hrtimer(timer, base);
++
++	unlock_hrtimer_base(timer, &flags);
++
++	return ret;
++
++}
++EXPORT_SYMBOL_GPL(hrtimer_try_to_cancel);
++
++/**
++ * hrtimer_cancel - cancel a timer and wait for the handler to finish.
++ * @timer:	the timer to be cancelled
++ *
++ * Returns:
++ *  0 when the timer was not active
++ *  1 when the timer was active
++ */
++int hrtimer_cancel(struct hrtimer *timer)
++{
++	for (;;) {
++		int ret = hrtimer_try_to_cancel(timer);
++
++		if (ret >= 0)
++			return ret;
++		cpu_relax();
++	}
++}
++EXPORT_SYMBOL_GPL(hrtimer_cancel);
++
++/**
++ * hrtimer_get_remaining - get remaining time for the timer
++ * @timer:	the timer to read
++ */
++ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
++{
++	struct hrtimer_clock_base *base;
++	unsigned long flags;
++	ktime_t rem;
++
++	base = lock_hrtimer_base(timer, &flags);
++	rem = hrtimer_expires_remaining(timer);
++	unlock_hrtimer_base(timer, &flags);
++
++	return rem;
++}
++EXPORT_SYMBOL_GPL(hrtimer_get_remaining);
++
++#ifdef CONFIG_NO_HZ
++/**
++ * hrtimer_get_next_event - get the time until next expiry event
++ *
++ * Returns the delta to the next expiry event or KTIME_MAX if no timer
++ * is pending.
++ */
++ktime_t hrtimer_get_next_event(void)
++{
++	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
++	struct hrtimer_clock_base *base = cpu_base->clock_base;
++	ktime_t delta, mindelta = { .tv64 = KTIME_MAX };
++	unsigned long flags;
++	int i;
++
++	raw_spin_lock_irqsave(&cpu_base->lock, flags);
++
++	if (!hrtimer_hres_active()) {
++		for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) {
++			struct hrtimer *timer;
++
++			if (!base->first)
++				continue;
++
++			timer = rb_entry(base->first, struct hrtimer, node);
++			delta.tv64 = hrtimer_get_expires_tv64(timer);
++			delta = ktime_sub(delta, base->get_time());
++			if (delta.tv64 < mindelta.tv64)
++				mindelta.tv64 = delta.tv64;
++		}
++	}
++
++	raw_spin_unlock_irqrestore(&cpu_base->lock, flags);
++
++	if (mindelta.tv64 < 0)
++		mindelta.tv64 = 0;
++	return mindelta;
++}
++#endif
++
++static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
++			   enum hrtimer_mode mode)
++{
++	struct hrtimer_cpu_base *cpu_base;
++
++	memset(timer, 0, sizeof(struct hrtimer));
++
++	cpu_base = &__raw_get_cpu_var(hrtimer_bases);
++
++	if (clock_id == CLOCK_REALTIME && mode != HRTIMER_MODE_ABS)
++		clock_id = CLOCK_MONOTONIC;
++
++	timer->base = &cpu_base->clock_base[clock_id];
++	hrtimer_init_timer_hres(timer);
++
++#ifdef CONFIG_TIMER_STATS
++	timer->start_site = NULL;
++	timer->start_pid = -1;
++	memset(timer->start_comm, 0, TASK_COMM_LEN);
++#endif
++}
++
++/**
++ * hrtimer_init - initialize a timer to the given clock
++ * @timer:	the timer to be initialized
++ * @clock_id:	the clock to be used
++ * @mode:	timer mode abs/rel
++ */
++void hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
++		  enum hrtimer_mode mode)
++{
++	debug_init(timer, clock_id, mode);
++	__hrtimer_init(timer, clock_id, mode);
++}
++EXPORT_SYMBOL_GPL(hrtimer_init);
++
++/**
++ * hrtimer_get_res - get the timer resolution for a clock
++ * @which_clock: which clock to query
++ * @tp:		 pointer to timespec variable to store the resolution
++ *
++ * Store the resolution of the clock selected by @which_clock in the
++ * variable pointed to by @tp.
++ */
++int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp)
++{
++	struct hrtimer_cpu_base *cpu_base;
++
++	cpu_base = &__raw_get_cpu_var(hrtimer_bases);
++	*tp = ktime_to_timespec(cpu_base->clock_base[which_clock].resolution);
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(hrtimer_get_res);
++
++static void __run_hrtimer(struct hrtimer *timer, ktime_t *now)
++{
++	struct hrtimer_clock_base *base = timer->base;
++	struct hrtimer_cpu_base *cpu_base = base->cpu_base;
++	enum hrtimer_restart (*fn)(struct hrtimer *);
++	int restart;
++
++	WARN_ON(!irqs_disabled());
++
++	debug_deactivate(timer);
++	__remove_hrtimer(timer, base, HRTIMER_STATE_CALLBACK, 0);
++	timer_stats_account_hrtimer(timer);
++	fn = timer->function;
++
++	/*
++	 * Because we run timers from hardirq context, there is no chance
++	 * they get migrated to another cpu, therefore its safe to unlock
++	 * the timer base.
++	 */
++	raw_spin_unlock(&cpu_base->lock);
++	trace_hrtimer_expire_entry(timer, now);
++	restart = fn(timer);
++	trace_hrtimer_expire_exit(timer);
++	raw_spin_lock(&cpu_base->lock);
++
++	/*
++	 * Note: We clear the CALLBACK bit after enqueue_hrtimer and
++	 * we do not reprogramm the event hardware. Happens either in
++	 * hrtimer_start_range_ns() or in hrtimer_interrupt()
++	 */
++	if (restart != HRTIMER_NORESTART) {
++		BUG_ON(timer->state != HRTIMER_STATE_CALLBACK);
++		enqueue_hrtimer(timer, base);
++	}
++
++	WARN_ON_ONCE(!(timer->state & HRTIMER_STATE_CALLBACK));
++
++	timer->state &= ~HRTIMER_STATE_CALLBACK;
++}
++
++#ifdef CONFIG_HIGH_RES_TIMERS
++
++/*
++ * High resolution timer interrupt
++ * Called with interrupts disabled
++ */
++void hrtimer_interrupt(struct clock_event_device *dev)
++{
++	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
++	struct hrtimer_clock_base *base;
++	ktime_t expires_next, now, entry_time, delta;
++	int i, retries = 0;
++
++	BUG_ON(!cpu_base->hres_active);
++	cpu_base->nr_events++;
++	dev->next_event.tv64 = KTIME_MAX;
++
++	entry_time = now = ktime_get();
++retry:
++	expires_next.tv64 = KTIME_MAX;
++
++	raw_spin_lock(&cpu_base->lock);
++	/*
++	 * We set expires_next to KTIME_MAX here with cpu_base->lock
++	 * held to prevent that a timer is enqueued in our queue via
++	 * the migration code. This does not affect enqueueing of
++	 * timers which run their callback and need to be requeued on
++	 * this CPU.
++	 */
++	cpu_base->expires_next.tv64 = KTIME_MAX;
++
++	base = cpu_base->clock_base;
++
++	for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
++		ktime_t basenow;
++		struct rb_node *node;
++
++		basenow = ktime_add(now, base->offset);
++
++		while ((node = base->first)) {
++			struct hrtimer *timer;
++
++			timer = rb_entry(node, struct hrtimer, node);
++
++			/*
++			 * The immediate goal for using the softexpires is
++			 * minimizing wakeups, not running timers at the
++			 * earliest interrupt after their soft expiration.
++			 * This allows us to avoid using a Priority Search
++			 * Tree, which can answer a stabbing querry for
++			 * overlapping intervals and instead use the simple
++			 * BST we already have.
++			 * We don't add extra wakeups by delaying timers that
++			 * are right-of a not yet expired timer, because that
++			 * timer will have to trigger a wakeup anyway.
++			 */
++
++			if (basenow.tv64 < hrtimer_get_softexpires_tv64(timer)) {
++				ktime_t expires;
++
++				expires = ktime_sub(hrtimer_get_expires(timer),
++						    base->offset);
++				if (expires.tv64 < expires_next.tv64)
++					expires_next = expires;
++				break;
++			}
++
++			__run_hrtimer(timer, &basenow);
++		}
++		base++;
++	}
++
++	/*
++	 * Store the new expiry value so the migration code can verify
++	 * against it.
++	 */
++	cpu_base->expires_next = expires_next;
++	raw_spin_unlock(&cpu_base->lock);
++
++	/* Reprogramming necessary ? */
++	if (expires_next.tv64 == KTIME_MAX ||
++	    !tick_program_event(expires_next, 0)) {
++		cpu_base->hang_detected = 0;
++		return;
++	}
++
++	/*
++	 * The next timer was already expired due to:
++	 * - tracing
++	 * - long lasting callbacks
++	 * - being scheduled away when running in a VM
++	 *
++	 * We need to prevent that we loop forever in the hrtimer
++	 * interrupt routine. We give it 3 attempts to avoid
++	 * overreacting on some spurious event.
++	 */
++	now = ktime_get();
++	cpu_base->nr_retries++;
++	if (++retries < 3)
++		goto retry;
++	/*
++	 * Give the system a chance to do something else than looping
++	 * here. We stored the entry time, so we know exactly how long
++	 * we spent here. We schedule the next event this amount of
++	 * time away.
++	 */
++	cpu_base->nr_hangs++;
++	cpu_base->hang_detected = 1;
++	delta = ktime_sub(now, entry_time);
++	if (delta.tv64 > cpu_base->max_hang_time.tv64)
++		cpu_base->max_hang_time = delta;
++	/*
++	 * Limit it to a sensible value as we enforce a longer
++	 * delay. Give the CPU at least 100ms to catch up.
++	 */
++	if (delta.tv64 > 100 * NSEC_PER_MSEC)
++		expires_next = ktime_add_ns(now, 100 * NSEC_PER_MSEC);
++	else
++		expires_next = ktime_add(now, delta);
++	tick_program_event(expires_next, 1);
++	printk_once(KERN_WARNING "hrtimer: interrupt took %llu ns\n",
++		    ktime_to_ns(delta));
++}
++
++/*
++ * local version of hrtimer_peek_ahead_timers() called with interrupts
++ * disabled.
++ */
++static void __hrtimer_peek_ahead_timers(void)
++{
++	struct tick_device *td;
++
++	if (!hrtimer_hres_active())
++		return;
++
++	td = &__get_cpu_var(tick_cpu_device);
++	if (td && td->evtdev)
++		hrtimer_interrupt(td->evtdev);
++}
++
++/**
++ * hrtimer_peek_ahead_timers -- run soft-expired timers now
++ *
++ * hrtimer_peek_ahead_timers will peek at the timer queue of
++ * the current cpu and check if there are any timers for which
++ * the soft expires time has passed. If any such timers exist,
++ * they are run immediately and then removed from the timer queue.
++ *
++ */
++void hrtimer_peek_ahead_timers(void)
++{
++	unsigned long flags;
++
++	local_irq_save(flags);
++	__hrtimer_peek_ahead_timers();
++	local_irq_restore(flags);
++}
++
++static void run_hrtimer_softirq(struct softirq_action *h)
++{
++	hrtimer_peek_ahead_timers();
++}
++
++#else /* CONFIG_HIGH_RES_TIMERS */
++
++static inline void __hrtimer_peek_ahead_timers(void) { }
++
++#endif	/* !CONFIG_HIGH_RES_TIMERS */
++
++/*
++ * Called from timer softirq every jiffy, expire hrtimers:
++ *
++ * For HRT its the fall back code to run the softirq in the timer
++ * softirq context in case the hrtimer initialization failed or has
++ * not been done yet.
++ */
++void hrtimer_run_pending(void)
++{
++	if (hrtimer_hres_active())
++		return;
++
++	/*
++	 * This _is_ ugly: We have to check in the softirq context,
++	 * whether we can switch to highres and / or nohz mode. The
++	 * clocksource switch happens in the timer interrupt with
++	 * xtime_lock held. Notification from there only sets the
++	 * check bit in the tick_oneshot code, otherwise we might
++	 * deadlock vs. xtime_lock.
++	 */
++	if (tick_check_oneshot_change(!hrtimer_is_hres_enabled()))
++		hrtimer_switch_to_hres();
++}
++
++/*
++ * Called from hardirq context every jiffy
++ */
++void hrtimer_run_queues(void)
++{
++	struct rb_node *node;
++	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
++	struct hrtimer_clock_base *base;
++	int index, gettime = 1;
++
++	if (hrtimer_hres_active())
++		return;
++
++	for (index = 0; index < HRTIMER_MAX_CLOCK_BASES; index++) {
++		base = &cpu_base->clock_base[index];
++
++		if (!base->first)
++			continue;
++
++		if (gettime) {
++			hrtimer_get_softirq_time(cpu_base);
++			gettime = 0;
++		}
++
++		raw_spin_lock(&cpu_base->lock);
++
++		while ((node = base->first)) {
++			struct hrtimer *timer;
++
++			timer = rb_entry(node, struct hrtimer, node);
++			if (base->softirq_time.tv64 <=
++					hrtimer_get_expires_tv64(timer))
++				break;
++
++			__run_hrtimer(timer, &base->softirq_time);
++		}
++		raw_spin_unlock(&cpu_base->lock);
++	}
++}
++
++/*
++ * Sleep related functions:
++ */
++static enum hrtimer_restart hrtimer_wakeup(struct hrtimer *timer)
++{
++	struct hrtimer_sleeper *t =
++		container_of(timer, struct hrtimer_sleeper, timer);
++	struct task_struct *task = t->task;
++
++	t->task = NULL;
++	if (task)
++		wake_up_process(task);
++
++	return HRTIMER_NORESTART;
++}
++
++void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task)
++{
++	sl->timer.function = hrtimer_wakeup;
++	sl->task = task;
++}
++EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);
++
++static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
++{
++	hrtimer_init_sleeper(t, current);
++
++	do {
++		set_current_state(TASK_INTERRUPTIBLE);
++		hrtimer_start_expires(&t->timer, mode);
++		if (!hrtimer_active(&t->timer))
++			t->task = NULL;
++
++		if (likely(t->task))
++			schedule();
++
++		hrtimer_cancel(&t->timer);
++		mode = HRTIMER_MODE_ABS;
++
++	} while (t->task && !signal_pending(current));
++
++	__set_current_state(TASK_RUNNING);
++
++	return t->task == NULL;
++}
++
++static int update_rmtp(struct hrtimer *timer, struct timespec __user *rmtp)
++{
++	struct timespec rmt;
++	ktime_t rem;
++
++	rem = hrtimer_expires_remaining(timer);
++	if (rem.tv64 <= 0)
++		return 0;
++	rmt = ktime_to_timespec(rem);
++
++	if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
++		return -EFAULT;
++
++	return 1;
++}
++
++long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
++{
++	struct hrtimer_sleeper t;
++	struct timespec __user  *rmtp;
++	int ret = 0;
++
++	hrtimer_init_on_stack(&t.timer, restart->nanosleep.index,
++				HRTIMER_MODE_ABS);
++	hrtimer_set_expires_tv64(&t.timer, restart->nanosleep.expires);
++
++	if (do_nanosleep(&t, HRTIMER_MODE_ABS))
++		goto out;
++
++	rmtp = restart->nanosleep.rmtp;
++	if (rmtp) {
++		ret = update_rmtp(&t.timer, rmtp);
++		if (ret <= 0)
++			goto out;
++	}
++
++	/* The other values in restart are already filled in */
++	ret = -ERESTART_RESTARTBLOCK;
++out:
++	destroy_hrtimer_on_stack(&t.timer);
++	return ret;
++}
++
++long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
++		       const enum hrtimer_mode mode, const clockid_t clockid)
++{
++	struct restart_block *restart;
++	struct hrtimer_sleeper t;
++	int ret = 0;
++	unsigned long slack;
++
++	slack = current->timer_slack_ns;
++	if (rt_task(current))
++		slack = 0;
++
++	hrtimer_init_on_stack(&t.timer, clockid, mode);
++	hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack);
++	if (do_nanosleep(&t, mode))
++		goto out;
++
++	/* Absolute timers do not update the rmtp value and restart: */
++	if (mode == HRTIMER_MODE_ABS) {
++		ret = -ERESTARTNOHAND;
++		goto out;
++	}
++
++	if (rmtp) {
++		ret = update_rmtp(&t.timer, rmtp);
++		if (ret <= 0)
++			goto out;
++	}
++
++	restart = &current_thread_info()->restart_block;
++	restart->fn = hrtimer_nanosleep_restart;
++	restart->nanosleep.index = t.timer.base->index;
++	restart->nanosleep.rmtp = rmtp;
++	restart->nanosleep.expires = hrtimer_get_expires_tv64(&t.timer);
++
++	ret = -ERESTART_RESTARTBLOCK;
++out:
++	destroy_hrtimer_on_stack(&t.timer);
++	return ret;
++}
++
++SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,
++		struct timespec __user *, rmtp)
++{
++	struct timespec tu;
++
++	if (copy_from_user(&tu, rqtp, sizeof(tu)))
++		return -EFAULT;
++
++	if (!timespec_valid(&tu))
++		return -EINVAL;
++
++	return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
++}
++
++/*
++ * Functions related to boot-time initialization:
++ */
++static void __cpuinit init_hrtimers_cpu(int cpu)
++{
++	struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
++	int i;
++
++	raw_spin_lock_init(&cpu_base->lock);
++
++	for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++)
++		cpu_base->clock_base[i].cpu_base = cpu_base;
++
++	hrtimer_init_hres(cpu_base);
++}
++
++#ifdef CONFIG_HOTPLUG_CPU
++
++static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base,
++				struct hrtimer_clock_base *new_base)
++{
++	struct hrtimer *timer;
++	struct rb_node *node;
++
++	while ((node = rb_first(&old_base->active))) {
++		timer = rb_entry(node, struct hrtimer, node);
++		BUG_ON(hrtimer_callback_running(timer));
++		debug_deactivate(timer);
++
++		/*
++		 * Mark it as STATE_MIGRATE not INACTIVE otherwise the
++		 * timer could be seen as !active and just vanish away
++		 * under us on another CPU
++		 */
++		__remove_hrtimer(timer, old_base, HRTIMER_STATE_MIGRATE, 0);
++		timer->base = new_base;
++		/*
++		 * Enqueue the timers on the new cpu. This does not
++		 * reprogram the event device in case the timer
++		 * expires before the earliest on this CPU, but we run
++		 * hrtimer_interrupt after we migrated everything to
++		 * sort out already expired timers and reprogram the
++		 * event device.
++		 */
++		enqueue_hrtimer(timer, new_base);
++
++		/* Clear the migration state bit */
++		timer->state &= ~HRTIMER_STATE_MIGRATE;
++	}
++}
++
++static void migrate_hrtimers(int scpu)
++{
++	struct hrtimer_cpu_base *old_base, *new_base;
++	int i;
++
++	BUG_ON(cpu_online(scpu));
++	tick_cancel_sched_timer(scpu);
++
++	local_irq_disable();
++	old_base = &per_cpu(hrtimer_bases, scpu);
++	new_base = &__get_cpu_var(hrtimer_bases);
++	/*
++	 * The caller is globally serialized and nobody else
++	 * takes two locks at once, deadlock is not possible.
++	 */
++	raw_spin_lock(&new_base->lock);
++	raw_spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
++
++	for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
++		migrate_hrtimer_list(&old_base->clock_base[i],
++				     &new_base->clock_base[i]);
++	}
++
++	raw_spin_unlock(&old_base->lock);
++	raw_spin_unlock(&new_base->lock);
++
++	/* Check, if we got expired work to do */
++	__hrtimer_peek_ahead_timers();
++	local_irq_enable();
++}
++
++#endif /* CONFIG_HOTPLUG_CPU */
++
++static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self,
++					unsigned long action, void *hcpu)
++{
++	int scpu = (long)hcpu;
++
++	switch (action) {
++
++	case CPU_UP_PREPARE:
++	case CPU_UP_PREPARE_FROZEN:
++		init_hrtimers_cpu(scpu);
++		break;
++
++#ifdef CONFIG_HOTPLUG_CPU
++	case CPU_DYING:
++	case CPU_DYING_FROZEN:
++		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DYING, &scpu);
++		break;
++	case CPU_DEAD:
++	case CPU_DEAD_FROZEN:
++	{
++		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DEAD, &scpu);
++		migrate_hrtimers(scpu);
++		break;
++	}
++#endif
++
++	default:
++		break;
++	}
++
++	return NOTIFY_OK;
++}
++
++static struct notifier_block __cpuinitdata hrtimers_nb = {
++	.notifier_call = hrtimer_cpu_notify,
++};
++
++void __init hrtimers_init(void)
++{
++	hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE,
++			  (void *)(long)smp_processor_id());
++	register_cpu_notifier(&hrtimers_nb);
++#ifdef CONFIG_HIGH_RES_TIMERS
++	open_softirq(HRTIMER_SOFTIRQ, run_hrtimer_softirq);
++#endif
++}
++
++/**
++ * schedule_hrtimeout_range_clock - sleep until timeout
++ * @expires:	timeout value (ktime_t)
++ * @delta:	slack in expires timeout (ktime_t)
++ * @mode:	timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL
++ * @clock:	timer clock, CLOCK_MONOTONIC or CLOCK_REALTIME
++ */
++int __sched
++schedule_hrtimeout_range_clock(ktime_t *expires, unsigned long delta,
++			       const enum hrtimer_mode mode, int clock)
++{
++	struct hrtimer_sleeper t;
++
++	/*
++	 * Optimize when a zero timeout value is given. It does not
++	 * matter whether this is an absolute or a relative time.
++	 */
++	if (expires && !expires->tv64) {
++		__set_current_state(TASK_RUNNING);
++		return 0;
++	}
++
++	/*
++	 * A NULL parameter means "inifinte"
++	 */
++	if (!expires) {
++		schedule();
++		__set_current_state(TASK_RUNNING);
++		return -EINTR;
++	}
++
++	hrtimer_init_on_stack(&t.timer, clock, mode);
++	hrtimer_set_expires_range_ns(&t.timer, *expires, delta);
++
++	hrtimer_init_sleeper(&t, current);
++
++	hrtimer_start_expires(&t.timer, mode);
++	if (!hrtimer_active(&t.timer))
++		t.task = NULL;
++
++	if (likely(t.task))
++		schedule();
++
++	hrtimer_cancel(&t.timer);
++	destroy_hrtimer_on_stack(&t.timer);
++
++	__set_current_state(TASK_RUNNING);
++
++	return !t.task ? 0 : -EINTR;
++}
++
++/**
++ * schedule_hrtimeout_range - sleep until timeout
++ * @expires:	timeout value (ktime_t)
++ * @delta:	slack in expires timeout (ktime_t)
++ * @mode:	timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL
++ *
++ * Make the current task sleep until the given expiry time has
++ * elapsed. The routine will return immediately unless
++ * the current task state has been set (see set_current_state()).
++ *
++ * The @delta argument gives the kernel the freedom to schedule the
++ * actual wakeup to a time that is both power and performance friendly.
++ * The kernel give the normal best effort behavior for "@expires+ at 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 at 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 at 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 at lkcl.net>
++ * Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris at redhat.com>
++ *
++ * tiny-shmem:
++ * Copyright (c) 2004, 2008 Matt Mackall <mpm at 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 at cs.sunysb.edu
++L:	unionfs at 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 at 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*"
diff --git a/recipes/nbd/files/nbd.h b/recipes/nbd/files/nbd.h
new file mode 100644
index 0000000..155719d
--- /dev/null
+++ b/recipes/nbd/files/nbd.h
@@ -0,0 +1,102 @@
+/*
+ * 1999 Copyright (C) Pavel Machek, pavel at ucw.cz. This code is GPL.
+ * 1999/11/04 Copyright (C) 1999 VMware, Inc. (Regis "HPReg" Duchesne)
+ *            Made nbd_end_request() use the io_request_lock
+ * 2001 Copyright (C) Steven Whitehouse
+ *            New nbd_end_request() for compatibility with new linux block
+ *            layer code.
+ * 2003/06/24 Louis D. Langholtz <ldl at aros.net>
+ *            Removed unneeded blksize_bits field from nbd_device struct.
+ *            Cleanup PARANOIA usage & code.
+ * 2004/02/19 Paul Clements
+ *            Removed PARANOIA, plus various cleanup and comments
+ */
+
+#ifndef LINUX_NBD_H
+#define LINUX_NBD_H
+
+#include <linux/types.h>
+
+#define NBD_SET_SOCK	_IO( 0xab, 0 )
+#define NBD_SET_BLKSIZE	_IO( 0xab, 1 )
+#define NBD_SET_SIZE	_IO( 0xab, 2 )
+#define NBD_DO_IT	_IO( 0xab, 3 )
+#define NBD_CLEAR_SOCK	_IO( 0xab, 4 )
+#define NBD_CLEAR_QUE	_IO( 0xab, 5 )
+#define NBD_PRINT_DEBUG	_IO( 0xab, 6 )
+#define NBD_SET_SIZE_BLOCKS	_IO( 0xab, 7 )
+#define NBD_DISCONNECT  _IO( 0xab, 8 )
+#define NBD_SET_TIMEOUT _IO( 0xab, 9 )
+
+enum {
+	NBD_CMD_READ = 0,
+	NBD_CMD_WRITE = 1,
+	NBD_CMD_DISC = 2
+};
+
+#define nbd_cmd(req) ((req)->cmd[0])
+
+/* userspace doesn't need the nbd_device structure */
+#ifdef __KERNEL__
+
+#include <linux/wait.h>
+#include <linux/mutex.h>
+
+/* values for flags field */
+#define NBD_READ_ONLY 0x0001
+#define NBD_WRITE_NOCHK 0x0002
+
+struct request;
+
+struct nbd_device {
+	int flags;
+	int harderror;		/* Code of hard error			*/
+	struct socket * sock;
+	struct file * file; 	/* If == NULL, device is not ready, yet	*/
+	int magic;
+
+	spinlock_t queue_lock;
+	struct list_head queue_head;	/* Requests waiting result */
+	struct request *active_req;
+	wait_queue_head_t active_wq;
+	struct list_head waiting_queue;	/* Requests to be sent */
+	wait_queue_head_t waiting_wq;
+
+	struct mutex tx_lock;
+	struct gendisk *disk;
+	int blksize;
+	u64 bytesize;
+	pid_t pid; /* pid of nbd-client, if attached */
+	int xmit_timeout;
+};
+
+#endif
+
+/* These are sent over the network in the request/reply magic fields */
+
+#define NBD_REQUEST_MAGIC 0x25609513
+#define NBD_REPLY_MAGIC 0x67446698
+/* Do *not* use magics: 0x12560953 0x96744668. */
+
+/*
+ * This is the packet used for communication between client and
+ * server. All data are in network byte order.
+ */
+struct nbd_request {
+	__be32 magic;
+	__be32 type;	/* == READ || == WRITE 	*/
+	char handle[8];
+	__be64 from;
+	__be32 len;
+} __attribute__ ((packed));
+
+/*
+ * This is the reply packet that nbd-server sends back to the client after
+ * it has completed an I/O request (or an error occurs).
+ */
+struct nbd_reply {
+	__be32 magic;
+	__be32 error;		/* 0 = ok, else error	*/
+	char handle[8];		/* handle you got from request	*/
+};
+#endif
diff --git a/recipes/nbd/nbd_2.8.7.bb.changed b/recipes/nbd/nbd_2.8.7.bb.changed
new file mode 100644
index 0000000..182ae2b
--- /dev/null
+++ b/recipes/nbd/nbd_2.8.7.bb.changed
@@ -0,0 +1,31 @@
+DESCRIPTION = "Network Block Device"
+HOMEPAGE = "http://nbd.sourceforge.net"
+LICENSE = "GPLv2"
+DEPENDS = "glib-2.0"
+
+SRC_URI = "${SOURCEFORGE_MIRROR}/${PN}/${PN}-${PV}.tar.bz2;md5sum=bc7995b4961385269abc645575bcaf4d \
+           file://cross-compile.patch \
+           file://nbd.h \
+"
+SRC_URI[md5sum] = "bc7995b4961385269abc645575bcaf4d"
+SRC_URI[sha256sum] = "a69d1690ad587d81b85c34d1ef9bf47abf0ba21dc96876d95dd6a9a193a859f1"
+
+inherit autotools
+
+do_unpack_extra(){
+    oenote Kernel Staging Dir: $STAGING_KERNEL_DIR
+    cp ${S}/../nbd.h ${S}
+}
+addtask unpack_extra after do_unpack before do_patch
+
+export NBD_H_LOCAL="1"
+
+PACKAGES = "nbd-client nbd-server nbd-client-dbg nbd-server-dbg"
+PACKAGES += "nbd-client-doc nbd-server-doc"
+
+FILES_nbd-client = "/usr/sbin/nbd-client"
+FILES_nbd-server = "/usr/bin/nbd-server"
+FILES_nbd-client-dbg += "/usr/sbin/.debug/nbd-client"
+FILES_nbd-server-dbg += "/usr/bin/.debug/nbd-server"
+FILES_nbd-client-doc = "/usr/share/man/man8/*"
+FILES_nbd-server-doc = "/usr/share/man/man1/*"
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





More information about the Openembedded-devel mailing list