Copyright (c) 2004-2005 Advanced Micro Devices, Inc.

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

Index: linux-2.6.11/Documentation/fb/geodefb.txt
===================================================================
--- /dev/null
+++ linux-2.6.11/Documentation/fb/geodefb.txt
@@ -0,0 +1,95 @@
+geodefb.txt
+
+This is the documentation for the AMD Geode LX framebuffer driver.
+
+Kernel Build Configuration Parameters
+-------------------------------------
+These kernel build parameters are operated using "make xconfig" or
+"make menuconfig" from the kernel source root directory.
+The parameter path to these parameters is:
+Device Drivers
+ Graphics Support
+  Support for frame buffer devices
+   AMD Geode generic framebuffer support
+    AMD Geode LX framebuffer driver
+     AMD Geode LX console acceleration
+     AMD Geode Framebuffer panel support
+
+Config_Param  Value   Definition
+============  =====   ==========
+FB_GEODE     (y/m/n)  Build AMD Geode generic framebuffer support
+FB_GEODE_LX    (y/n)  Build AMD Geode LX framebuffer driver (selects CIMARRON)
+FB_GEODE_ACCEL (y/n)  Build AMD Geode LX console acceleration
+FB_GEODE_PANEL (y/n)  Build AMD Geode Framebuffer panel support
+
+
+Kernel Boot Command Line Argument Options
+-----------------------------------------
+If the geodefb driver has been built into the kernel (not as a module), then
+driver setup options are available via the kernel cmdline interface.
+
+kernel boot command line argument options are available using:
+video=geodefb:<option>[,<option>...]
+option strings are one of three types:
+identifier        as in video=geodefb:off
+identifier=value  as in video=geodefb:vfreq=85
+noidenfier        as in video=geodefb:noflatpanel
+
+video=option      Definition
+============      ==========
+off             - specify this option to disable the geodefb.
+vfreq=<value>   - specifies the default vertical refresh (default 60) 
+vmode=<string>  - specifies a mode text string. (default = 640x480@60-16)
+no/compression  - disables/enables compression display acceleration (default disabled)
+maxmem          - Maximum amount of memory to use for the FB (default 12288K)
+no/accel        - disables/enables rendering accelerations (default enabled)
+
+if the module was build with CONFIG_FB_GEODE_PANEL applied
+no/flatpanel    - disable/enables flatpanel operation (default enabled)
+no/fphwscale    - disable/enables flatpanel hardware scaling (default enabled)
+
+
+Module Parameters:
+------------------ 
+If geodefb was built as a module, then parameters can be applied
+when the modules is installed (via insmod/modprobe or modules.conf).
+When installing the module, new options are specified as follows:
+modprobe geodefb <option> <option>  ... or
+insmod /path/geodefb.ko <option> <option>  ...
+
+Module parameters:
+parameter     Definition
+=========     ==========
+vfreq       - Set initial video refresh rate in cycles per second
+vmode       - Set initial mode to <xres>x<vres>@refresh-bpp
+compression - Compression support (0=disabled or 1=enabled)
+maxmem      - Maximum amount of memory to use for the FB (in Kbytes)
+accel       - HW accleration support (0=disabled or 1=enabled)
+
+if the module was build with CONFIG_FB_GEODE_PANEL applied
+flatpanel   - Flatpanel support (0=disabled or 1=enabled)
+fphwscale   - FP Hardware Scaling (0=disabled or 1=enabled)
+
+
+Video Modes:
+------------
+The permissible mode parameter values are:
+geometry
+  640x480, 800x600, 1024x768, 1152x864, 1280x1024, 1600x1200, 1920x1600
+refresh
+  56, 60, 70, 72, 75, 85, 90, 100
+bpp
+  8, 16, 32
+
+The permissible mode parameter combinations are defined by the cimarron
+driver, and in cimarron by cim_modes.c.
+
+
+Notes:
+-----
+Since building the geodefb normally select the cimarron driver, please
+review the procedures for building cimarron.  To have the framebuffer
+driver work properly with X windows, it is normally necessary to create
+device nodes for /dev/cimarron and possibly links for /dev/videox.
+See cimarron module and lxv4l2 module documentation.
+
Index: linux-2.6.11/Documentation/geode.txt
===================================================================
--- /dev/null
+++ linux-2.6.11/Documentation/geode.txt
@@ -0,0 +1,24 @@
+Running Linux on the AMD Geode Architecture
+=======================================
+
+Configuration Options
+
+The following options enable various Geode and CS5535 features:
+
+CONFIG_MGEODE_GX - Enable GX processor support
+CONFIG_MGEODE_LX - Enable LX processor support
+CONFIG_BLK_DEV_CS5535 - Enable IDE support for the CS5535 companion chip
+CONFIG_HW_RANDOM - Includes support for the LX hardware RNG
+CONFIG_FB_GEODE - Enable Geode framebuffer support
+	CONFIG_FB_GEODE_LX - Enable LX framebuffer support
+	CONFIG_FB_GEODE_ACCEL - Use acceleration for console drawing
+	CONFIG_FB_GEODE_PANEL - Support TFT panels
+CONFIG_USB_OHCI_HCD - Enable OHCI USB support for the CS5535 companion chip
+CONFIG_CIMARRON - (Usually selected automatically) - Support the LX graphics 
+		  abstraction layer.
+
+In addition - the following kernel option should be selected as a module
+if you are using the Geode ALSA driver modules:
+
+CONFIG_SND_AC97_CODEC
+
Index: linux-2.6.11/Documentation/usb/amd5536udc.txt
===================================================================
--- /dev/null
+++ linux-2.6.11/Documentation/usb/amd5536udc.txt
@@ -0,0 +1,184 @@
+-------------------------------------------------------------------------------
+Howto for Linux device driver for the AMD5536 USB Device Controller (UDC)
+for gadget driver stack
+-------------------------------------------------------------------------------
+
+Author: Thomas Dahlmann
+
+INTRODUCTION:
+
+The AMD5536 UDC is part of x86 southbridge AMD5536 and MIPS CPU Au1200.
+It is a DMA capable usb device controller. The usb port is shared
+between host and UDC. The on-chip UOC controller is used to switch the
+usb port between host, UDC and neutral. So amd5536uoc driver is needed
+to get the UDC operating.
+
+-------------------------------------------------------------------------------
+WHAT YOU NEED:
+-------------------------------------------------------------------------------
+
+copy/replace following files to /usr/src/linux/drivers/usb/gadget
+        amd5536udc.c
+        amd5536udc.h
+        amd5536uoc.c
+        amd5536uoc.h
+        ether.c
+        file_storage.c
+        zero.c
+	inode.c
+        gadget_chips.h
+        Makefile
+        Kconfig 
+
+-------------------------------------------------------------------------------
+HOW TO INSTALL IT:
+-------------------------------------------------------------------------------
+
+change to directory /usr/src/linux
+
+configure gadget as module:
+        "make menuconfig"
+        under "Code maturity level options" choose "Prompt for development ..."
+        goto "Device Drivers"
+        goto "USB support" -> "USB Gadget support"
+        choose "Support for USB Gadgets" as module
+        under choice "USB Peripheral Controller" choose "AMD5536-UDC"
+        under "USB Gadget Drivers"
+        choose "Gadget Zero" as module or
+        choose "Ethernet Gagdet" as module or
+        choose "File-backed Storage Gadget" as module
+        exit and save config
+
+compile and install modules:
+        "make modules modules_install"
+
+-------------------------------------------------------------------------------
+HOW TO USE IT:
+-------------------------------------------------------------------------------
+
+*** How to load FILE-BACKED STORAGE gadget driver - mass storage ***
+enable USB mass storage support for linux host:
+        change to directory /usr/src/linux
+        "make menuconfig"
+        under "File systems" choose "DOS/FAT/NT filesystems"
+        choose "MSDOS fs support"
+        under "Device Drivers" under "SCSI device support"
+                choose "SCSI device support"
+                choose "SCSI generic support"
+        under "Device Drivers" under "USB support" in section 
+                "USB Device Class drivers" choose
+                "USB Mass Storage support"
+        compile new kernel
+create disk file:
+        "dd bs=1M count=128 if=/dev/zero of=/tmp/disk"
+        => creates a 128Mbyte image file /tmp/disk
+load modules:
+        "modprobe amd5536udc"  
+        "modprobe g_file_storage file=/tmp/disk"
+        Note: multiple file arguments are possible, each will be a separate
+              drive for the host side, furthermore devices such as /dev/hda
+              (whole disk will be used) or /dev/hda1 (partition) can be used
+              as argument too
+        "modprobe amd5536uoc"
+create a primary FAT16 disk partition via linux host site:
+        "fdisk /dev/sda", make FAT16 prim. partition
+        => "n", "p", "1", "<RETURN>", "<RETURN>", "t", "6", "w",
+        "mkdosfs /dev/sda1"
+        "sync"
+create primary disk partition via Windows XP host site:
+        right click on "My Computer"
+        choose "Manage" => "Disk Management"
+        choose usb disk and follow instructions of partition menu
+mount usb mass storage device on linux host:
+        make directory "/mnt/gadget/"
+        "mount -t msdos /dev/sda1 /mnt/gadget"
+
+***  How to access files of disk image on UDC side ***
+When files were copied from host to UDC mass storage device then files
+are inside the monolitic disk image (see above) on UDC side. This
+disk image can be mounted via the loopback device driver to a 
+directory on UDC side to access these files.
+Steps on UDC side:
+        enable kernel support for loopback device
+        change to directory /usr/src/linux
+        "make menuconfig"
+        under "Block devices" choose "Loopback device support"
+                and recompile the kernel
+        determine offset inside disk image:
+        "fdisk -l -u disk_image", output is like:
+>> You must set cylinders.
+>> You can do this from the extra functions menu.
+>>
+>> Disk /tmp/disk128: 5 heads, 52 sectors, 0 cylinders
+>> Units = sectors of 1 * 512 bytes
+>>
+>>         Device Boot    Start       End    Blocks   Id  System
+>> /tmp/disk128p1            52    262079    131014    6  FAT16
+
+        get offset my multiplying start value by sector size:
+        52 * 512 = 26624
+        mount disk image:
+        "mount -o loop,offset=26624 -t msdos disk_image /mnt"
+
+
+*** How to load ZERO gadget driver - simple BULK loop back ***
+load modules:
+UDC driver:
+        (a) Slave/Fifo mode:       "modprobe amd5536udc use_dma=0"
+        (b) DMA Buffer Fill mode:  "modprobe amd5536udc use_dma=1" 
+        default:
+        (c) DMA PPBNDU mode:       "modprobe amd5536udc"  
+        (d) DMA PPBDU mode:        "modprobe amd5536udc use_dma=1 use_dma_ppb=1 use_dma_ppb_du=1"  
+        (e) fullspeed mode:        "modprobe amd5536udc use_fullspeed=1", can be combined
+                                    with all dma modes  
+        (f) special higspeed
+            tx buffer size:        "modprobe amd5536udc hs_tx_buf=<buf_size in dwords>"
+                                   example: "modprobe amd5536udc use_dma=1 hs_tx_buf=128"
+                                            => buffer size = 512 bytes (=bulk max packet)
+Gadget Zero driver:
+        (a) Bulk loop:             "modprobe g_zero"
+        (b) Int loop:              "modprobe g_zero use_interrupt_traffic=1"
+        (c) Source/Sink            "modprobe g_zero loopdefault=0"
+                                   OUT data must all be zero's
+        (d) Source/Sink count      "modprobe g_zero loopdefault=0 pattern=1"
+                                   each OUT packet must count modulo63 (0,1,..,62,0,1,..) 
+UOC driver:                        "modprobe amd5536uoc"
+example:
+        "modprobe amd5536udc"
+        "modprobe g_zero"
+        "modprobe amd5536uoc"
+        => loads driver for DMA PPBNDU mode and Bulk loop  
+
+
+*** How to use ETHERNET gadget driver (CDC protocol) ***
+                   with Linux Host
+UDC side bringup: 
+        load gadget modules
+        "modprobe amd5536udc"  
+        "modprobe g_ether"
+        "modprobe amd5536uoc"
+        "ifconfig usb0 192.168.0.2"  
+Host side bringup: 
+        install support for CDC Ethernet:
+        change to directory /usr/src/linux
+        "make menuconfig"
+        under "Device Drivers" under "USB support" under
+        "USB Network adapters" choose
+        "Multi-purpose USB Networking Framework"
+        choose "CDC Ethernet support"
+        compile mew kernel
+        "modprobe CDCEther"
+        "ifconfig eth1 192.168.0.1"
+        note: assuming there is one network card assigned to eth0,
+                otherwise kernel messages of CDC Ethernet module show
+                which interface (ethX) is used 
+Use network connection: 
+        after bringup of host and UDC side it behaves like a normal
+                ethernet connection between host and UDC
+        test the connection:
+        host side: "ping -I eth1 192.168.0.2"
+        UDC side : "ping -I usb0 192.168.0.1"
+        note: the "-I" option assures that the USB cable is used, the
+                option can be omitted when the routing table is setup to avoid
+                using other network interfaces as eth0
+
Index: linux-2.6.11/Documentation/usb/amd5536uoc.txt
===================================================================
--- /dev/null
+++ linux-2.6.11/Documentation/usb/amd5536uoc.txt
@@ -0,0 +1,89 @@
+--------------------------------------------------------------------------
+Howto for Linux device driver for the AMD5536 USB Options Controller (UOC)
+--------------------------------------------------------------------------
+
+Author: Karsten Boge
+
+(1)Introduction
+===============
+
+The AMD5536 UOC is part of x86 southbridge AMD5536.
+The USB port is shared between the USB Host Controller 
+and the USB Device Controller as defined in BIOS setup. 
+The on-chip UOC controller is used to switch the
+usb port between host, UDC and neutral.
+The amd5536uoc driver is needed to get the 
+USB Device Controller operating.
+
+(2) Patches
+===========
+
+udc.patch:
+    This containes the UDC driver as together
+    with the UOC driver
+
+(3) Driver source code installation
+===================================
+
+- New files for UOC:
+    drivers/usb/gadget/amd5536uoc.h
+    drivers/usb/gadget/amd5536uoc.c
+
+(4) BIOS setup
+==================
+
+    PCI Configuration
+        UDC:    Enabled
+        OTG:    Enabled
+        Port 4 assignment:  Device
+
+(4) Config options
+==================
+
+    <M/*> Support for USB Gadgets
+         USB Periheral Controller (?choice?)
+             (X) AMD5536UDC
+
+    The role of the UOC port can be defined 
+    within the BIOS setup exclusively. 
+    
+    Selecting the amd5536udc driver results in 
+    building the amd5536uoc driver too.
+    If "Support for USB Gadgets" is configured to be statically
+    linked both modules will be linked into the kernel image 
+    otherwise an additional module called amd5536uoc will be built
+    
+
+(5) Compile and install
+=======================
+
+    If global USB support is configured to be used as
+    kernel module (usbcore.o) (recomended):
+    
+      make modules SUBDIRS=drivers/usb/gadget
+      make modules_install
+
+    If it's linked into the kernel image an new kernel
+    image must be compiled and created before.
+
+(6) Usage
+=========
+
+    modprobe amd5536uoc
+
+    This will load the module and other modules which provide
+    interfaces used by the UOC driver (usbcore, amd5536udc).
+
+    The amd5536uoc driver is needed to power up the uoc logic 
+    which controls the pullup resistors connected to either 
+    the D+ or D- USB pins.
+    The function of this pullup resistors is to signal the host 
+    that a device is connected, and at which speed the device 
+    operates.
+    
+    Make sure the USB port is assigned to device within the 
+    BIOS setup otherwise the modules will not be loaded. 
+
+
+
+
Index: linux-2.6.11/MAINTAINERS
===================================================================
--- linux-2.6.11.orig/MAINTAINERS
+++ linux-2.6.11/MAINTAINERS
@@ -255,6 +255,13 @@ P:	Ivan Kokshaysky
 M:	ink@jurassic.park.msu.ru
 S:	Maintained for 2.4; PCI support for 2.6.
 
+AMD GEODE PROCESSOR/CHIPSET SUPPORT
+P:
+M:
+L:	info-linux@geode.amd.com
+W:	http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
+S:	Supported
+
 APM DRIVER
 P:	Stephen Rothwell
 M:	sfr@canb.auug.org.au
Index: linux-2.6.11/Makefile
===================================================================
--- linux-2.6.11.orig/Makefile
+++ linux-2.6.11/Makefile
@@ -1,7 +1,8 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 11
-EXTRAVERSION =
+AMDVERSION = 02.03.0100
+EXTRAVERSION = -geode-$(AMDVERSION)
 NAME=Woozy Numbat
 
 # *DOCUMENTATION*
Index: linux-2.6.11/arch/i386/Kconfig
===================================================================
--- linux-2.6.11.orig/arch/i386/Kconfig
+++ linux-2.6.11/arch/i386/Kconfig
@@ -178,6 +178,7 @@ config M386
 	  - "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
 	  - "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
 	  - "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
+	  - "Geode GX/LX" for AMD Geode GX and LX processors 
 	  - "Crusoe" for the Transmeta Crusoe series.
 	  - "Efficeon" for the Transmeta Efficeon series.
 	  - "Winchip-C6" for original IDT Winchip.
@@ -275,6 +276,21 @@ config MK8
 	  use of some extended instructions, and passes appropriate optimization
 	  flags to GCC.
 
+config MGEODE_GX
+	bool "Geode GX"
+	help
+	  Select this for AMD Geode GX and LX processors.
+	  Enables use of some extended instructions, and
+	  passes appropriate optimization flags to GCC.
+
+config MGEODE_LX
+	bool "Geode LX"
+	help
+	  Select this for AMD Geode LX processors.
+	  Enables use of some extended instructions, allows
+	  you to use various on-chip devices, and passes appropriate
+	  optimization flags to GCC.
+
 config MCRUSOE
 	bool "Crusoe"
 	help
@@ -358,9 +374,9 @@ config X86_XADD
 
 config X86_L1_CACHE_SHIFT
 	int
-	default "7" if MPENTIUM4 || X86_GENERIC
+	default "7" if MPENTIUM4 || X86_GENERIC 
 	default "4" if X86_ELAN || M486 || M386
-	default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2
+	default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_GX || MGEODE_LX
 	default "6" if MK7 || MK8 || MPENTIUMM
 
 config RWSEM_GENERIC_SPINLOCK
@@ -424,12 +440,12 @@ config X86_INTEL_USERCOPY
 
 config X86_USE_PPRO_CHECKSUM
 	bool
-	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
+	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_GX || MGEODE_LX
 	default y
 
 config X86_USE_3DNOW
 	bool
-	depends on MCYRIXIII || MK7
+	depends on MCYRIXIII || MK7 || MGEODE_GX || MGEODE_LX
 	default y
 
 config X86_OOSTORE
@@ -530,7 +546,7 @@ config PREEMPT_BKL
 
 config X86_UP_APIC
 	bool "Local APIC support on uniprocessors" if !SMP
-	depends on !(X86_VISWS || X86_VOYAGER)
+	depends on !(X86_VISWS || X86_VOYAGER || MGEODE_GX || MGEODE_LX)
 	---help---
 	  A local APIC (Advanced Programmable Interrupt Controller) is an
 	  integrated interrupt controller in the CPU. If you have a single-CPU
@@ -729,6 +745,7 @@ config HIGHMEM4G
 
 config HIGHMEM64G
 	bool "64GB"
+	depends on !MGEODE_GX && !MGEODE_LX
 	help
 	  Select this if you have a 32-bit processor and more than 4
 	  gigabytes of physical RAM.
Index: linux-2.6.11/arch/i386/defconfig
===================================================================
--- linux-2.6.11.orig/arch/i386/defconfig
+++ linux-2.6.11/arch/i386/defconfig
@@ -1,21 +1,25 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-geode-2.00.00-pre1
+# Fri Jun  3 11:45:26 2005
 #
 CONFIG_X86=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
+CONFIG_BROKEN_ON_SMP=y
 
 #
 # General setup
 #
+CONFIG_LOCALVERSION=""
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -23,18 +27,22 @@ CONFIG_POSIX_MQUEUE=y
 CONFIG_SYSCTL=y
 CONFIG_AUDIT=y
 CONFIG_AUDITSYSCALL=y
-CONFIG_LOG_BUF_SHIFT=15
+CONFIG_LOG_BUF_SHIFT=14
 CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
 
 #
 # Loadable module support
@@ -43,6 +51,7 @@ CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
 CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
@@ -66,10 +75,12 @@ CONFIG_X86_PC=y
 # CONFIG_MPENTIUMII is not set
 # CONFIG_MPENTIUMIII is not set
 # CONFIG_MPENTIUMM is not set
-CONFIG_MPENTIUM4=y
+# CONFIG_MPENTIUM4 is not set
 # CONFIG_MK6 is not set
 # CONFIG_MK7 is not set
 # CONFIG_MK8 is not set
+# CONFIG_MGEODE_GX is not set
+CONFIG_MGEODE_LX=y
 # CONFIG_MCRUSOE is not set
 # CONFIG_MEFFICEON is not set
 # CONFIG_MWINCHIPC6 is not set
@@ -80,27 +91,19 @@ CONFIG_MPENTIUM4=y
 # CONFIG_X86_GENERIC is not set
 CONFIG_X86_CMPXCHG=y
 CONFIG_X86_XADD=y
-CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_X86_L1_CACHE_SHIFT=5
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_X86_WP_WORKS_OK=y
 CONFIG_X86_INVLPG=y
 CONFIG_X86_BSWAP=y
 CONFIG_X86_POPAD_OK=y
-CONFIG_X86_GOOD_APIC=y
-CONFIG_X86_INTEL_USERCOPY=y
 CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_X86_USE_3DNOW=y
 # CONFIG_HPET_TIMER is not set
-# CONFIG_HPET_EMULATE_RTC is not set
-CONFIG_SMP=y
-CONFIG_NR_CPUS=8
-CONFIG_SCHED_SMT=y
-CONFIG_PREEMPT=y
-CONFIG_X86_LOCAL_APIC=y
-CONFIG_X86_IO_APIC=y
-CONFIG_X86_TSC=y
-CONFIG_X86_MCE=y
-CONFIG_X86_MCE_NONFATAL=y
-CONFIG_X86_MCE_P4THERMAL=y
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_X86_MCE is not set
 # CONFIG_TOSHIBA is not set
 # CONFIG_I8K is not set
 # CONFIG_MICROCODE is not set
@@ -115,18 +118,16 @@ CONFIG_NOHIGHMEM=y
 # CONFIG_HIGHMEM4G is not set
 # CONFIG_HIGHMEM64G is not set
 # CONFIG_MATH_EMULATION is not set
-CONFIG_MTRR=y
+# CONFIG_MTRR is not set
 # CONFIG_EFI is not set
-CONFIG_IRQBALANCE=y
-CONFIG_HAVE_DEC_LOCK=y
 # CONFIG_REGPARM is not set
 
 #
 # Power management options (ACPI, APM)
 #
 CONFIG_PM=y
-CONFIG_SOFTWARE_SUSPEND=y
-# CONFIG_PM_DISK is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
 
 #
 # ACPI (Advanced Configuration and Power Interface) Support
@@ -139,11 +140,14 @@ CONFIG_ACPI_SLEEP_PROC_FS=y
 CONFIG_ACPI_AC=y
 CONFIG_ACPI_BATTERY=y
 CONFIG_ACPI_BUTTON=y
+# CONFIG_ACPI_VIDEO is not set
 CONFIG_ACPI_FAN=y
 CONFIG_ACPI_PROCESSOR=y
 CONFIG_ACPI_THERMAL=y
 # CONFIG_ACPI_ASUS is not set
+# CONFIG_ACPI_IBM is not set
 # CONFIG_ACPI_TOSHIBA is not set
+CONFIG_ACPI_BLACKLIST_YEAR=0
 # CONFIG_ACPI_DEBUG is not set
 CONFIG_ACPI_BUS=y
 CONFIG_ACPI_EC=y
@@ -151,6 +155,7 @@ CONFIG_ACPI_POWER=y
 CONFIG_ACPI_PCI=y
 CONFIG_ACPI_SYSTEM=y
 # CONFIG_X86_PM_TIMER is not set
+# CONFIG_ACPI_CONTAINER is not set
 
 #
 # APM (Advanced Power Management) BIOS Support
@@ -173,19 +178,21 @@ CONFIG_PCI_GOANY=y
 CONFIG_PCI_BIOS=y
 CONFIG_PCI_DIRECT=y
 CONFIG_PCI_MMCONFIG=y
-# CONFIG_PCI_USE_VECTOR is not set
+# CONFIG_PCIEPORTBUS is not set
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
-CONFIG_ISA=y
-# CONFIG_EISA is not set
+# CONFIG_ISA is not set
 # CONFIG_MCA is not set
 # CONFIG_SCx200 is not set
 
 #
-# PCMCIA/CardBus support
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
 #
-# CONFIG_PCMCIA is not set
-CONFIG_PCMCIA_PROBE=y
 
 #
 # PCI Hotplug Support
@@ -196,8 +203,8 @@ CONFIG_PCMCIA_PROBE=y
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_MISC=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
 
 #
 # Device Drivers
@@ -206,7 +213,9 @@ CONFIG_BINFMT_MISC=y
 #
 # Generic Driver Options
 #
-CONFIG_FW_LOADER=m
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -228,30 +237,36 @@ CONFIG_PARPORT_PC_CML1=y
 #
 # Plug and Play support
 #
-CONFIG_PNP=y
-# CONFIG_PNP_DEBUG is not set
-
-#
-# Protocols
-#
-# CONFIG_ISAPNP is not set
-# CONFIG_PNPBIOS is not set
+# CONFIG_PNP is not set
 
 #
 # Block devices
 #
 CONFIG_BLK_DEV_FD=y
-# CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_CARMEL is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
 CONFIG_LBD=y
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -262,6 +277,7 @@ CONFIG_BLK_DEV_IDE=y
 #
 # Please see Documentation/ide.txt for help/info on IDE drives
 #
+# CONFIG_BLK_DEV_IDE_SATA is not set
 # CONFIG_BLK_DEV_HD_IDE is not set
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
@@ -270,26 +286,22 @@ CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
-CONFIG_IDE_TASKFILE_IO=y
 
 #
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_CMD640=y
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_IDEPNP is not set
+# CONFIG_BLK_DEV_CMD640 is not set
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_GENERIC is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_RZ1000=y
+# CONFIG_BLK_DEV_RZ1000 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
@@ -299,6 +311,7 @@ CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5520 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
+CONFIG_BLK_DEV_CS5535=y
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
@@ -313,7 +326,6 @@ CONFIG_BLK_DEV_PIIX=y
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
 # CONFIG_IDE_ARM is not set
-# CONFIG_IDE_CHIPSETS is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
 CONFIG_IDEDMA_AUTO=y
@@ -346,54 +358,35 @@ CONFIG_CHR_DEV_SG=y
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
 #
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
-CONFIG_SCSI_DPT_I2O=m
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_MEGARAID is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_SVW is not set
-CONFIG_SCSI_ATA_PIIX=y
-# CONFIG_SCSI_SATA_PROMISE is not set
-CONFIG_SCSI_SATA_SX4=m
-# CONFIG_SCSI_SATA_SIL is not set
-CONFIG_SCSI_SATA_SIS=m
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_EATA is not set
 # CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
 # CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_PPA is not set
 # CONFIG_SCSI_IMM is not set
-# CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-CONFIG_SCSI_IPR=m
-# CONFIG_SCSI_IPR_TRACE is not set
-# CONFIG_SCSI_IPR_DUMP is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
@@ -403,22 +396,12 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
-# CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
@@ -431,33 +414,7 @@ CONFIG_SCSI_QLA2XXX=y
 #
 # IEEE 1394 (FireWire) support
 #
-CONFIG_IEEE1394=y
-
-#
-# Subsystem Options
-#
-# CONFIG_IEEE1394_VERBOSEDEBUG is not set
-# CONFIG_IEEE1394_OUI_DB is not set
-# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set
-
-#
-# Device Drivers
-#
-
-#
-# Texas Instruments PCILynx requires I2C
-#
-CONFIG_IEEE1394_OHCI1394=y
-
-#
-# Protocol Drivers
-#
-# CONFIG_IEEE1394_VIDEO1394 is not set
-# CONFIG_IEEE1394_SBP2 is not set
-# CONFIG_IEEE1394_ETH1394 is not set
-# CONFIG_IEEE1394_DV1394 is not set
-CONFIG_IEEE1394_RAWIO=y
-# CONFIG_IEEE1394_CMP is not set
+# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
@@ -489,66 +446,11 @@ CONFIG_IP_MULTICAST=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_IP_TCPDIAG is not set
+# CONFIG_IP_TCPDIAG_IPV6 is not set
 # CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=y
-# CONFIG_IP_NF_FTP is not set
-# CONFIG_IP_NF_IRC is not set
-# CONFIG_IP_NF_TFTP is not set
-# CONFIG_IP_NF_AMANDA is not set
-CONFIG_IP_NF_QUEUE=y
-CONFIG_IP_NF_IPTABLES=y
-CONFIG_IP_NF_MATCH_LIMIT=y
-CONFIG_IP_NF_MATCH_IPRANGE=y
-CONFIG_IP_NF_MATCH_MAC=y
-CONFIG_IP_NF_MATCH_PKTTYPE=y
-CONFIG_IP_NF_MATCH_MARK=y
-CONFIG_IP_NF_MATCH_MULTIPORT=y
-CONFIG_IP_NF_MATCH_TOS=y
-CONFIG_IP_NF_MATCH_RECENT=y
-CONFIG_IP_NF_MATCH_ECN=y
-CONFIG_IP_NF_MATCH_DSCP=y
-CONFIG_IP_NF_MATCH_AH_ESP=y
-CONFIG_IP_NF_MATCH_LENGTH=y
-CONFIG_IP_NF_MATCH_TTL=y
-CONFIG_IP_NF_MATCH_TCPMSS=y
-CONFIG_IP_NF_MATCH_HELPER=y
-CONFIG_IP_NF_MATCH_STATE=y
-CONFIG_IP_NF_MATCH_CONNTRACK=y
-CONFIG_IP_NF_MATCH_OWNER=y
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-CONFIG_IP_NF_NAT=y
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=y
-CONFIG_IP_NF_TARGET_REDIRECT=y
-CONFIG_IP_NF_TARGET_NETMAP=y
-CONFIG_IP_NF_TARGET_SAME=y
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_MANGLE=y
-CONFIG_IP_NF_TARGET_TOS=y
-CONFIG_IP_NF_TARGET_ECN=y
-CONFIG_IP_NF_TARGET_DSCP=y
-CONFIG_IP_NF_TARGET_MARK=y
-CONFIG_IP_NF_TARGET_CLASSIFY=y
-CONFIG_IP_NF_TARGET_LOG=y
-CONFIG_IP_NF_TARGET_ULOG=y
-CONFIG_IP_NF_TARGET_TCPMSS=y
-CONFIG_IP_NF_ARPTABLES=y
-CONFIG_IP_NF_ARPFILTER=y
-CONFIG_IP_NF_ARP_MANGLE=y
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_RAW=m
+# CONFIG_NETFILTER is not set
 
 #
 # SCTP Configuration (EXPERIMENTAL)
@@ -566,13 +468,12 @@ CONFIG_IP_NF_RAW=m
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -584,11 +485,10 @@ CONFIG_IP_NF_RAW=m
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
+# CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
 
 #
 # ARCnet devices
@@ -603,27 +503,18 @@ CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
 
 #
 # Tulip family network device support
 #
 # CONFIG_NET_TULIP is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_CS89x0 is not set
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 # CONFIG_E100 is not set
@@ -641,7 +532,6 @@ CONFIG_8139TOO_PIO=y
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_NET_POCKET is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -654,14 +544,14 @@ CONFIG_8139TOO_PIO=y
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_IXGB is not set
-CONFIG_S2IO=m
-# CONFIG_S2IO_NAPI is not set
+# CONFIG_S2IO is not set
 
 #
 # Token Ring devices
@@ -724,6 +614,8 @@ CONFIG_SERIO_I8042=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PARKBD is not set
 # CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
 
 #
 # Input Device Drivers
@@ -737,9 +629,6 @@ CONFIG_KEYBOARD_ATKBD=y
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
@@ -765,15 +654,14 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 # Non-8250 serial port support
 #
+CONFIG_SERIAL_GEODE_UART2=y
 CONFIG_SERIAL_CORE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-CONFIG_PRINTER=y
-# CONFIG_LP_CONSOLE is not set
+# CONFIG_PRINTER is not set
 # CONFIG_PPDEV is not set
 # CONFIG_TIPAR is not set
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
@@ -796,29 +684,12 @@ CONFIG_PRINTER=y
 #
 # Ftape, the floppy tape device driver
 #
-CONFIG_AGP=y
-# CONFIG_AGP_ALI is not set
-# CONFIG_AGP_ATI is not set
-# CONFIG_AGP_AMD is not set
-# CONFIG_AGP_AMD64 is not set
-CONFIG_AGP_INTEL=y
-CONFIG_AGP_INTEL_MCH=m
-# CONFIG_AGP_NVIDIA is not set
-# CONFIG_AGP_SIS is not set
-# CONFIG_AGP_SWORKS is not set
-# CONFIG_AGP_VIA is not set
-# CONFIG_AGP_EFFICEON is not set
-CONFIG_DRM=y
-# CONFIG_DRM_TDFX is not set
-# CONFIG_DRM_GAMMA is not set
-# CONFIG_DRM_R128 is not set
-# CONFIG_DRM_RADEON is not set
-# CONFIG_DRM_I810 is not set
-CONFIG_DRM_I830=y
-# CONFIG_DRM_MGA is not set
-# CONFIG_DRM_SIS is not set
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
 # CONFIG_MWAVE is not set
 # CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
 # CONFIG_HANGCHECK_TIMER is not set
 
 #
@@ -827,6 +698,11 @@ CONFIG_DRM_I830=y
 # CONFIG_I2C is not set
 
 #
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
 # Misc devices
 #
 # CONFIG_IBM_ASM is not set
@@ -851,7 +727,6 @@ CONFIG_DRM_I830=y
 # Console display driver support
 #
 CONFIG_VGA_CONSOLE=y
-# CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 
 #
@@ -865,7 +740,6 @@ CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
-CONFIG_SND_RAWMIDI=y
 CONFIG_SND_SEQUENCER=y
 # CONFIG_SND_SEQ_DUMMY is not set
 CONFIG_SND_OSSEMUL=y
@@ -878,7 +752,6 @@ CONFIG_SND_SEQUENCER_OSS=y
 #
 # Generic devices
 #
-CONFIG_SND_MPU401_UART=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_VIRMIDI is not set
 # CONFIG_SND_MTPAV is not set
@@ -886,37 +759,12 @@ CONFIG_SND_MPU401_UART=y
 # CONFIG_SND_MPU401 is not set
 
 #
-# ISA devices
-#
-# CONFIG_SND_AD1848 is not set
-# CONFIG_SND_CS4231 is not set
-# CONFIG_SND_CS4232 is not set
-# CONFIG_SND_CS4236 is not set
-# CONFIG_SND_ES1688 is not set
-# CONFIG_SND_ES18XX is not set
-# CONFIG_SND_GUSCLASSIC is not set
-# CONFIG_SND_GUSEXTREME is not set
-# CONFIG_SND_GUSMAX is not set
-# CONFIG_SND_INTERWAVE is not set
-# CONFIG_SND_INTERWAVE_STB is not set
-# CONFIG_SND_OPTI92X_AD1848 is not set
-# CONFIG_SND_OPTI92X_CS4231 is not set
-# CONFIG_SND_OPTI93X is not set
-# CONFIG_SND_SB8 is not set
-# CONFIG_SND_SB16 is not set
-# CONFIG_SND_SBAWE is not set
-# CONFIG_SND_WAVEFRONT is not set
-# CONFIG_SND_CMI8330 is not set
-# CONFIG_SND_OPL3SA2 is not set
-# CONFIG_SND_SGALAXY is not set
-# CONFIG_SND_SSCAPE is not set
-
-#
 # PCI devices
 #
-CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_AC97_CODEC=m
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
 # CONFIG_SND_AU8810 is not set
 # CONFIG_SND_AU8820 is not set
 # CONFIG_SND_AU8830 is not set
@@ -925,6 +773,8 @@ CONFIG_SND_AC97_CODEC=y
 # CONFIG_SND_CS46XX is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_CA0106 is not set
 # CONFIG_SND_KORG1212 is not set
 # CONFIG_SND_MIXART is not set
 # CONFIG_SND_NM256 is not set
@@ -944,16 +794,18 @@ CONFIG_SND_AC97_CODEC=y
 # CONFIG_SND_FM801 is not set
 # CONFIG_SND_ICE1712 is not set
 # CONFIG_SND_ICE1724 is not set
-CONFIG_SND_INTEL8X0=y
+# CONFIG_SND_INTEL8X0 is not set
 # CONFIG_SND_INTEL8X0M is not set
 # CONFIG_SND_SONICVIBES is not set
 # CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
 
 #
-# ALSA USB devices
+# USB devices
 #
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_USX2Y is not set
 
 #
 # Open Sound System
@@ -972,6 +824,10 @@ CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -981,6 +837,7 @@ CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_OHCI_HCD is not set
 CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
@@ -989,9 +846,14 @@ CONFIG_USB_UHCI_HCD=y
 # CONFIG_USB_BLUETOOTH_TTY is not set
 # CONFIG_USB_MIDI is not set
 # CONFIG_USB_ACM is not set
-CONFIG_USB_PRINTER=y
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_RW_DETECT is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
@@ -1002,7 +864,7 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 
 #
-# USB Human Interface Devices (HID)
+# USB Input Devices
 #
 CONFIG_USB_HID=y
 CONFIG_USB_HIDINPUT=y
@@ -1013,7 +875,7 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
-CONFIG_USB_EGALAX=m
+# CONFIG_USB_EGALAX is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
 
@@ -1022,7 +884,6 @@ CONFIG_USB_EGALAX=m
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
 
 #
 # USB Multimedia devices
@@ -1034,7 +895,7 @@ CONFIG_USB_EGALAX=m
 #
 
 #
-# USB Network adaptors
+# USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
@@ -1057,22 +918,37 @@ CONFIG_USB_EGALAX=m
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
 # CONFIG_USB_AUERSWALD 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_CYTHERM=m
-CONFIG_USB_PHIDGETSERVO=m
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_TEST is not set
 
 #
+# USB ATM/DSL drivers
+#
+
+#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1086,10 +962,15 @@ CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
 
@@ -1100,6 +981,7 @@ CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
 CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
 
 #
 # DOS/FAT/NT Filesystems
@@ -1107,6 +989,8 @@ CONFIG_UDF_FS=y
 CONFIG_FAT_FS=y
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -1118,6 +1002,7 @@ CONFIG_SYSFS=y
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
@@ -1153,6 +1038,7 @@ CONFIG_LOCKD=y
 CONFIG_EXPORTFS=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
@@ -1193,6 +1079,7 @@ CONFIG_NLS_CODEPAGE_437=y
 # 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
@@ -1211,23 +1098,21 @@ CONFIG_NLS_ISO8859_1=y
 #
 # Profiling support
 #
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
+# CONFIG_PROFILING is not set
 
 #
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_EARLY_PRINTK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_FRAME_POINTER is not set
+CONFIG_EARLY_PRINTK=y
 CONFIG_4KSTACKS=y
-CONFIG_X86_FIND_SMP_CONFIG=y
-CONFIG_X86_MPPARSE=y
 
 #
 # Security options
 #
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
@@ -1236,13 +1121,17 @@ CONFIG_X86_MPPARSE=y
 # CONFIG_CRYPTO is not set
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
+# CONFIG_CRC_CCITT is not set
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
-CONFIG_X86_SMP=y
-CONFIG_X86_HT=y
+# CONFIG_CIMARRON is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_X86_BIOS_REBOOT=y
-CONFIG_X86_TRAMPOLINE=y
-CONFIG_X86_STD_RESOURCES=y
 CONFIG_PC=y
Index: linux-2.6.11/arch/i386/kernel/apm.c
===================================================================
--- linux-2.6.11.orig/arch/i386/kernel/apm.c
+++ linux-2.6.11/arch/i386/kernel/apm.c
@@ -1061,22 +1061,23 @@ static int apm_engage_power_management(u
  
 static int apm_console_blank(int blank)
 {
-	int	error;
-	u_short	state;
+	int error, i;
+	u_short state;
+	u_short dev[3] = { 0x100, 0x1FF, 0x101 };
 
 	state = blank ? APM_STATE_STANDBY : APM_STATE_READY;
-	/* Blank the first display device */
-	error = set_power_state(0x100, state);
-	if ((error != APM_SUCCESS) && (error != APM_NO_ERROR)) {
-		/* try to blank them all instead */
-		error = set_power_state(0x1ff, state);
-		if ((error != APM_SUCCESS) && (error != APM_NO_ERROR))
-			/* try to blank device one instead */
-			error = set_power_state(0x101, state);
+
+	for (i = 0; i < 3; i++) {		
+		error = set_power_state(dev[i], state);
+
+		if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
+			return 1;
+
+		if (error == APM_NOT_ENGAGED)
+			break;	       
 	}
-	if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
-		return 1;
-	if (error == APM_NOT_ENGAGED) {
+
+	if (error == APM_NOT_ENGAGED && state != APM_STATE_READY) {
 		static int tried;
 		int eng_error;
 		if (tried++ == 0) {
Index: linux-2.6.11/arch/i386/kernel/cpu/amd.c
===================================================================
--- linux-2.6.11.orig/arch/i386/kernel/cpu/amd.c
+++ linux-2.6.11/arch/i386/kernel/cpu/amd.c
@@ -145,6 +145,13 @@ static void __init init_amd(struct cpuin
 					set_bit(X86_FEATURE_K6_MTRR, c->x86_capability);
 				break;
 			}
+
+			if ( c->x86_model == 10 ) {
+				/* AMD Geode LX is model 10 */
+				/* placeholder for any needed mods */
+				break;
+			}
+			
 			break;
 
 		case 6: /* An Athlon/Duron */
Index: linux-2.6.11/arch/i386/kernel/cpu/cyrix.c
===================================================================
--- linux-2.6.11.orig/arch/i386/kernel/cpu/cyrix.c
+++ linux-2.6.11/arch/i386/kernel/cpu/cyrix.c
@@ -346,6 +346,50 @@ static void __init init_cyrix(struct cpu
 	return;
 }
 
+
+static void __init init_nsc(struct cpuinfo_x86 *c)
+{
+
+
+	/* Handle the National Semiconductor models with non-Cyrix init */
+	if ( (c->x86 == 5) && (c->x86_model >= 4 && c->x86_model <= 5)) {
+		/* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
+		   3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
+		clear_bit(0*32+31, c->x86_capability);
+
+		get_model_name(c);
+
+		switch ( c->x86_model ) {
+                case 4: /* GX1/SCxx00 */
+
+			/* TODO Finish up the GX1/SCxx00 detection */
+                        /* GX1 uses bits 16 and 24 differently - 
+                           you could probably just do 
+
+                           clear_bit(0*32+16, &c->x86_capability);
+                           clear_bit(0*32+24, &c->x86_capability);
+
+                           since I don't think the kernel supports
+                           FPU-CMOV or Cyrix MMX.  Unsure tho.
+
+                           Also checking GX1 cache here needs to be done -
+                           display_cacheinfo() won't work according to
+                           AMD specs.
+                        */
+
+                        break;
+
+                case 5: /* GX */
+                        display_cacheinfo(c);
+                        break;
+		}
+	} else {
+		/* invoke the 'base class' */
+		init_cyrix(c);
+	}
+}
+		
+
 /*
  * Cyrix CPUs without cpuid or with cpuid not yet enabled can be detected
  * by the fact that they preserve the flags across the division of 5/2.
@@ -426,7 +470,7 @@ int __init cyrix_init_cpu(void)
 static struct cpu_dev nsc_cpu_dev __initdata = {
 	.c_vendor	= "NSC",
 	.c_ident 	= { "Geode by NSC" },
-	.c_init		= init_cyrix,
+	.c_init		= init_nsc,
 	.c_identify	= generic_identify,
 };
 
Index: linux-2.6.11/drivers/char/hw_random.c
===================================================================
--- linux-2.6.11.orig/drivers/char/hw_random.c
+++ linux-2.6.11/drivers/char/hw_random.c
@@ -1,4 +1,10 @@
 /*
+        Added support for the AMD Geode LX RNG 
+	(c) Copyright 2004-2005 Advanced Micro Devices, Inc.  
+	<jordan.crouse@amd.com>
+
+	derived from
+
  	Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
 	(c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
  
@@ -95,6 +101,13 @@ static unsigned int via_data_present (vo
 static u32 via_data_read (void);
 #endif
 
+#ifdef CONFIG_MGEODE_LX
+static int __init geode_init(struct pci_dev *dev);
+static void geode_cleanup(void);
+static unsigned int geode_data_present (void);
+static u32 geode_data_read (void);
+#endif
+
 struct rng_operations {
 	int (*init) (struct pci_dev *dev);
 	void (*cleanup) (void);
@@ -122,6 +135,9 @@ enum {
 	rng_hw_intel,
 	rng_hw_amd,
 	rng_hw_via,
+#ifdef CONFIG_MGEODE_LX
+	rng_hw_geode,
+#endif
 };
 
 static struct rng_operations rng_vendor_ops[] = {
@@ -139,6 +155,11 @@ static struct rng_operations rng_vendor_
 	/* rng_hw_via */
 	{ via_init, via_cleanup, via_data_present, via_data_read, 1 },
 #endif
+
+#ifdef CONFIG_MGEODE_LX
+	/* rng_hw_geode */
+	{ geode_init, geode_cleanup, geode_data_present, geode_data_read, 4 }
+#endif
 };
 
 /*
@@ -159,6 +180,10 @@ static struct pci_device_id rng_pci_tbl[
 	{ 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
 	{ 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
 
+#ifdef CONFIG_MGEODE_LX
+	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LX_AES,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_geode },
+#endif
 	{ 0, },	/* terminate list */
 };
 MODULE_DEVICE_TABLE (pci, rng_pci_tbl);
@@ -460,7 +485,55 @@ static void via_cleanup(void)
 }
 #endif
 
+#ifdef CONFIG_MGEODE_LX
+
+/***********************************************************************
+ *
+ * AMD Geode RNG operations
+ *
+ */
+
+static void __iomem *geode_rng_base = 0x0; 
+
+#define GEODE_RNG_DATA_REG   0x50
+#define GEODE_RNG_STATUS_REG 0x54
+
+static u32 geode_data_read(void) {
+	u32 val;
 
+	val = *((u32 *) (geode_rng_base + GEODE_RNG_DATA_REG));
+	return val;
+}
+
+static unsigned int geode_data_present(void) {
+	u32 val;
+
+	val = *((u32 *) (geode_rng_base + GEODE_RNG_STATUS_REG));
+	return val;
+}
+
+static void geode_cleanup(void) {
+	iounmap(geode_rng_base);
+  	geode_rng_base = NULL;
+}
+
+static int geode_init(struct pci_dev *dev) {		
+	u32 rng_base = pci_resource_start(dev, 0);
+	if (!rng_base) return 1;
+
+	geode_rng_base = ioremap(rng_base, 0x58);
+
+	if (geode_rng_base == NULL) {
+		printk(KERN_ERR PFX "Cannot ioremap RNG memory\n");
+		return -EBUSY;
+	}
+
+	printk(KERN_INFO PFX "Geode RNG registers at %p\n", geode_rng_base);
+	return 0;
+}
+
+#endif
+       
 /***********************************************************************
  *
  * /dev/hwrandom character device handling (major 10, minor 183)
@@ -577,7 +650,7 @@ static int __init rng_init (void)
 
 	DPRINTK ("ENTER\n");
 
-	/* Probe for Intel, AMD RNGs */
+	/* Probe for Intel, AMD, Geode RNGs */
 	for_each_pci_dev(pdev) {
 		ent = pci_match_device (rng_pci_tbl, pdev);
 		if (ent) {
Index: linux-2.6.11/drivers/char/vt_ioctl.c
===================================================================
--- linux-2.6.11.orig/drivers/char/vt_ioctl.c
+++ linux-2.6.11/drivers/char/vt_ioctl.c
@@ -36,6 +36,10 @@
 char vt_dont_switch;
 extern struct tty_driver *console_driver;
 
+/* Adding a notifier chain when we go from VT_TEXT to VT_GRAPHICS */
+
+struct notifier_block *console_notifier_list;
+
 #define VT_IS_IN_USE(i)	(console_driver->ttys[i] && console_driver->ttys[i]->count)
 #define VT_BUSY(i)	(VT_IS_IN_USE(i) || i == fg_console || vc_cons[i].d == sel_cons)
 
@@ -474,6 +478,7 @@ int vt_ioctl(struct tty_struct *tty, str
 		 * XXX It should at least call into the driver, fbdev's definitely
 		 * need to restore their engine state. --BenH
 		 */
+
 		if (!perm)
 			return -EPERM;
 		switch (arg) {
@@ -490,8 +495,17 @@ int vt_ioctl(struct tty_struct *tty, str
 		if (vt_cons[console]->vc_mode == (unsigned char) arg)
 			return 0;
 		vt_cons[console]->vc_mode = (unsigned char) arg;
+
 		if (console != fg_console)
 			return 0;
+
+		if (arg == KD_TEXT)
+			notifier_call_chain(&console_notifier_list, 
+					    CONSOLE_EVENT_SWITCH_TEXT, 0);
+		else if (arg == KD_GRAPHICS)
+			notifier_call_chain(&console_notifier_list,
+					    CONSOLE_EVENT_SWITCH_GRAPHICS, 0);
+
 		/*
 		 * explicitly blank/unblank the screen if switching modes
 		 */
Index: linux-2.6.11/drivers/ide/Kconfig
===================================================================
--- linux-2.6.11.orig/drivers/ide/Kconfig
+++ linux-2.6.11/drivers/ide/Kconfig
@@ -540,6 +540,14 @@ config BLK_DEV_CS5530
 
 	  It is safe to say Y to this question.
 
+config BLK_DEV_CS5535
+	tristate "AMD CS5535 chipset support"
+	help
+	  Include support for UDMA on the National Semiconductor/AMD 5535 
+	  chipset. This will automatically be detected and configured if found.
+
+	  It is safe to say Y to this question.
+
 config BLK_DEV_HPT34X
 	tristate "HPT34X chipset support"
 	help
Index: linux-2.6.11/drivers/ide/pci/Makefile
===================================================================
--- linux-2.6.11.orig/drivers/ide/pci/Makefile
+++ linux-2.6.11/drivers/ide/pci/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_BLK_DEV_ATIIXP)		+= atiixp.
 obj-$(CONFIG_BLK_DEV_CMD64X)		+= cmd64x.o
 obj-$(CONFIG_BLK_DEV_CS5520)		+= cs5520.o
 obj-$(CONFIG_BLK_DEV_CS5530)		+= cs5530.o
+obj-$(CONFIG_BLK_DEV_CS5535)		+= cs5535.o
 obj-$(CONFIG_BLK_DEV_SC1200)		+= sc1200.o
 obj-$(CONFIG_BLK_DEV_CY82C693)		+= cy82c693.o
 obj-$(CONFIG_BLK_DEV_HPT34X)		+= hpt34x.o
Index: linux-2.6.11/drivers/ide/pci/amd74xx.c
===================================================================
--- linux-2.6.11.orig/drivers/ide/pci/amd74xx.c
+++ linux-2.6.11/drivers/ide/pci/amd74xx.c
@@ -72,6 +72,7 @@ static struct amd_ide_chip {
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE,	0x50, AMD_UDMA_133 },
+    { PCI_DEVICE_ID_AMD_CS5536_IDE,             0x40, AMD_UDMA_100 },		/* AMD Hiddensee */ 
 	{ 0 }
 };
 
@@ -487,6 +488,7 @@ static ide_pci_device_t amd74xx_chipsets
 	/* 12 */ DECLARE_NV_DEV("NFORCE3-250-SATA2"),
 	/* 13 */ DECLARE_NV_DEV("NFORCE-CK804"),
 	/* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"),
+	/* 15 */ DECLARE_AMD_DEV("AMD5536"),
 };
 
 static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -521,6 +523,7 @@ static struct pci_device_id amd74xx_pci_
 #endif
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
+	{ PCI_VENDOR_ID_AMD,    PCI_DEVICE_ID_AMD_CS5536_IDE, 	        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 },
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
Index: linux-2.6.11/drivers/ide/pci/cs5535.c
===================================================================
--- /dev/null
+++ linux-2.6.11/drivers/ide/pci/cs5535.c
@@ -0,0 +1,352 @@
+/* <LIC_AMD_STD>
+ * Copyright (c) 2004-2005 Advanced Micro Devices, Inc.
+ * 
+ * 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 COPYING
+ * </LIC_AMD_STD>  */
+/* <CTL_AMD_STD>
+ * </CTL_AMD_STD>  */
+/* <DOC_AMD_STD>
+ *  CS5535 documentation available from AMD.
+ * </DOC_AMD_STD>  */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/msr.h>
+
+#include "ide-timing.h"
+#include "cs5535.h"
+
+#if defined(DISPLAY_CS5535_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static u8 cs5535_proc = 0;
+static struct pci_dev *bmide_dev;
+static u8 w80 = 0;
+
+static int cs5535_get_info (char *buffer, char **addr, off_t offset, int count)
+{
+	char *p = buffer;
+	unsigned long bibma = pci_resource_start(bmide_dev, 4);
+
+	u8  c0 = 0;
+
+	/*
+	 * at that point bibma+0x2 et bibma+0xa are byte registers
+	 * to investigate:
+	 */
+
+	c0 = inb_p((u16)bibma + 0x02);
+
+	p += sprintf(p, "\n                                "
+		     "AMD/NS 5535 Chipset.\n");
+
+	p += sprintf(p, "--------------- drive0 --------- drive1 ------\n");
+	p += sprintf(p, "DMA enabled:    %s              %s\n",(c0&0x20) ? "yes" : "no ",
+		     (c0&0x40) ? "yes" : "no ");
+
+	pci_read_config_byte(bmide_dev, CS5535_CABLE_DETECT, &c0);
+
+	p += sprintf(p, "80 Wire Cable:  %s              %s\n", (c0 & 1) ? "yes" : "no", 
+		     (c0 & 2) ? "yes" :  "no");
+	
+	return p-buffer;
+}
+
+#endif /* DISPLAY_CS5535_TIMINGS && CONFIG_PROC_FS */
+  
+/* Format I PIO settings. We seperate out cmd and data for safer timings */
+
+static unsigned int cs5535_pio_cmd_timings[5] = 
+{ 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 };
+static unsigned int cs5535_pio_dta_timings[5] = 
+{ 0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131 };
+
+static unsigned int cs5535_mwdma_timings[3] = 
+{ 0x7F0FFFF3, 0x7F035352, 0x7f024241 };
+
+static unsigned int cs5535_udma_timings[5] = 
+{ 0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061 };
+
+/* Macros to check if the register is the reset value -  reset value is an
+   invalid timing and indicates the register has not been set previously */
+
+#define CS5535_BAD_PIO(timings) ( (timings&~0x80000000)==0x00009172 )
+#define CS5535_BAD_DMA(timings) ( (timings & 0x000FFFFF) == 0x00077771 )
+
+#define DEFAULT_PIO   ( (cs5535_pio_cmd_timings[0] << 16) | cs5535_pio_dta_timings[0] )
+
+static u8 cs5535_get_bios_settings(int unit) {
+
+	u32 pio, dma, dummy;
+	int i;
+
+	rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, dma, dummy);   
+	rdmsr(unit ? ATAC_CH0D1_PIO : ATAC_CH0D0_PIO, pio, dummy);
+
+	if (!CS5535_BAD_DMA(dma)) {
+		for(i = 0; i < 5; i++) 
+			if (cs5535_udma_timings[i] == (dma & 0x7FFFFFFF))
+				return XFER_UDMA_0 + i;
+		
+		for(i = 0; i < 3; i++) 
+			if (cs5535_mwdma_timings[i] == (dma & 0x7FFFFFFF))
+				return  XFER_MW_DMA_0 + i;
+	}
+
+	for(i = 0; i < 5; i++) 
+		if ((pio & 0xFFFF) == cs5535_pio_dta_timings[i])
+			return XFER_PIO_0 + i;
+	
+	return 0;
+}
+	
+static u8 cs5535_get_pio_mode(int unit) {
+
+	u32 reg, dummy;
+	int i;
+
+	rdmsr(unit ? ATAC_CH0D1_PIO : ATAC_CH0D0_PIO, reg, dummy);
+	
+	for(i = 0; i < 5; i++) {
+		if ((reg & 0xFFFF) == cs5535_pio_dta_timings[i])
+			return i;
+	}
+
+	BUG();
+	return 0;
+}
+
+static void cs5535_set_speed(ide_drive_t *drive, u8 speed)  {
+
+	u32 reg, dummy;
+	int unit = drive->select.b.unit;
+
+	if (speed >= XFER_PIO_0 && speed <= XFER_PIO_4) {
+		u8 data1 = speed - XFER_PIO_0;
+		u8 data2 = cs5535_get_pio_mode(!unit);
+
+		u8 cmd = (data1 < data2) ? data1 : data2;
+
+		/* Write the other drive timings */
+		reg = (cs5535_pio_cmd_timings[cmd] << 16) | cs5535_pio_dta_timings[data2];
+		wrmsr(!unit ? ATAC_CH0D1_PIO : ATAC_CH0D0_PIO, reg, 0);
+
+		/* Write our drive timings*/
+		reg = (cs5535_pio_cmd_timings[cmd] << 16) | cs5535_pio_dta_timings[data1];
+		wrmsr(unit ? ATAC_CH0D1_PIO : ATAC_CH0D0_PIO, reg, 0);
+
+		/* Write the Format 1 bit in the DMA register */
+		rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy);    
+		wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg | 0x80000000, 0);
+	}
+	else {
+		rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy);
+		
+		
+		if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_7) 
+			reg = (reg & 0x80000000) | cs5535_udma_timings[speed - XFER_UDMA_0];
+		else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) 
+			reg = (reg & 0x80000000) | cs5535_mwdma_timings[speed - XFER_MW_DMA_0];
+		else { 
+			printk(KERN_INFO "cs5535:  Invalid speed 0x%x requested.\n", speed);
+			return;
+		}
+		wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, 0);
+	}
+}
+
+static int cs5535_set_drive(ide_drive_t *drive, u8 speed) 
+{       
+	if (speed != drive->current_speed)
+		ide_config_drive_speed(drive, speed);
+	
+	cs5535_set_speed(drive, speed);	
+
+	return 0;
+}
+
+/* tuneproc tunes the PIO speed of the device.
+   It is only called during init when autotune = IDE_TUNE_AUTO,
+   so we can avoid doing any default checking.
+*/
+
+static void cs5535_tuneproc (ide_drive_t *drive,u8 pio) 
+{ 	
+	u8 speed = 0;
+
+ 	if (pio == 255)
+		speed = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO);
+	else if (pio < 100) 
+		speed = XFER_PIO_0 + min_t(byte, pio, 5);
+	else if (pio < 200)
+		speed = XFER_MW_DMA_0 + min_t(byte, (pio - 100), 2);
+	else 
+		speed = XFER_UDMA_0 + min_t(byte, (pio - 200), 7);
+			
+	cs5535_set_drive(drive, speed);
+}
+
+static int cs5535_config_dma(ide_drive_t *drive) {
+	
+	int unit = drive->select.b.unit;
+	u8 speed = 0;
+	unsigned long map = XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA | (w80) ? XFER_UDMA_66 : 0;
+	
+	if (drive->autotune == IDE_TUNE_DEFAULT) {
+		drive->autotune = IDE_TUNE_NOAUTO;
+		
+		speed = cs5535_get_bios_settings(unit);
+
+		if (speed != 0) {
+			if (!drive->init_speed)
+				drive->init_speed = speed;
+
+			drive->current_speed = speed;
+		}
+	}
+
+	if (!speed) {
+		speed = ide_find_best_mode(drive, map);
+		cs5535_set_drive(drive, speed);
+	}
+	
+	if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
+                return HWIF(drive)->ide_dma_on(drive);
+
+        return HWIF(drive)->ide_dma_off_quietly(drive);		
+}
+
+static unsigned int __init init_chipset_cs5535 (struct pci_dev *dev, const char *name)
+{
+	u8 bit;
+
+#if defined(DISPLAY_CS5535_TIMINGS) && defined(CONFIG_PROC_FS)
+	if (!cs5535_proc)
+	{
+		cs5535_proc = 1;
+		bmide_dev = dev;
+		ide_pci_create_host_proc("cs5535", cs5535_get_info);
+	}
+#endif 
+
+	pci_read_config_byte(dev, CS5535_CABLE_DETECT, &bit);
+	w80 = bit & 1;  /* Remember if we have a 80 wire cable */
+
+	return 0;
+}
+
+static void __init init_hwif_cs5535 (ide_hwif_t *hwif)
+{
+	unsigned long dummy;
+	u32           timings;
+	
+	hwif->autodma = 0;
+	hwif->tuneproc = &cs5535_tuneproc;
+	hwif->speedproc = &cs5535_set_drive;
+	hwif->ide_dma_check = &cs5535_config_dma;
+
+	hwif->atapi_dma = 1;
+	
+	/* We always support UDMA 0, 1 and 2 */
+
+	hwif->ultra_mask = 0x07;
+	hwif->mwdma_mask = 0x07;
+	
+	/* If a 80 wire adapter is attached, add in 3 and 4 */
+	if (w80) hwif->ultra_mask |= 0x18;
+	       
+	hwif->udma_four = w80;  /* w80 = 1 if a 80 conductor line is attached */
+	
+	if (hwif->mate)
+		hwif->serialized = hwif->mate->serialized = 1;
+
+	hwif->drives[0].autotune = IDE_TUNE_DEFAULT;
+	hwif->drives[1].autotune = IDE_TUNE_DEFAULT;
+
+	rdmsr(ATAC_CH0D0_PIO,timings,dummy);
+
+	if (CS5535_BAD_PIO(timings)) {
+		wrmsr(ATAC_CH0D0_PIO, DEFAULT_PIO, 0);	  
+		hwif->drives[0].autotune = IDE_TUNE_AUTO;
+	}
+	
+	rdmsr(ATAC_CH0D1_PIO,timings,dummy);
+
+	if (CS5535_BAD_PIO(timings))  {
+		wrmsr(ATAC_CH0D1_PIO,DEFAULT_PIO,0);
+		hwif->drives[1].autotune = IDE_TUNE_AUTO;
+	}
+	
+	if (!noautodma) hwif->autodma = 1;
+		
+	hwif->drives[0].autodma = hwif->autodma;
+	hwif->drives[1].autodma = hwif->autodma;
+}
+
+static int __devinit cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	ide_setup_pci_device(dev, &cs5535_chipsets[id->driver_data]);
+	return 0;
+}
+
+static struct pci_device_id cs5535_pci_tbl[] __devinitdata = 
+{
+	{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ 0, },
+};
+MODULE_DEVICE_TABLE(pci, cs5535_pci_tbl);
+
+static struct pci_driver driver = {
+	.name       = "CS5535 IDE",
+	.id_table   = cs5535_pci_tbl,
+	.probe      = cs5535_init_one,
+};
+
+
+static int cs5535_ide_init(void)
+{
+	return ide_pci_register_driver(&driver);
+}
+
+static void cs5535_ide_exit(void)
+{
+	ide_pci_unregister_driver(&driver);
+}
+
+module_init(cs5535_ide_init);
+module_exit(cs5535_ide_exit);
+
+MODULE_AUTHOR("AMD");
+MODULE_DESCRIPTION("PCI driver module for AMD CS5535 IDE");
+MODULE_LICENSE("GPL");
+
Index: linux-2.6.11/drivers/ide/pci/cs5535.h
===================================================================
--- /dev/null
+++ linux-2.6.11/drivers/ide/pci/cs5535.h
@@ -0,0 +1,72 @@
+/* <LIC_AMD_STD>
+ * Copyright (c) 2004-2005 Advanced Micro Devices, Inc.
+ * 
+ * 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 COPYING
+ * </LIC_AMD_STD>  */
+/* <CTL_AMD_STD>
+ * </CTL_AMD_STD>  */
+/* <DOC_AMD_STD>
+ * </DOC_AMD_STD>  */
+
+#ifndef CS5535_H
+#define CS5535_H
+
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+
+#define DISPLAY_CS5535_TIMINGS
+
+#define MSR_ATAC_BASE    0x51300000
+#define ATAC_GLD_MSR_CAP (MSR_ATAC_BASE+0)
+#define ATAC_GLD_MSR_CONFIG    (MSR_ATAC_BASE+0x01)
+#define ATAC_GLD_MSR_SMI       (MSR_ATAC_BASE+0x02)
+#define ATAC_GLD_MSR_ERROR     (MSR_ATAC_BASE+0x03)
+#define ATAC_GLD_MSR_PM        (MSR_ATAC_BASE+0x04)
+#define ATAC_GLD_MSR_DIAG      (MSR_ATAC_BASE+0x05)
+#define ATAC_IO_BAR            (MSR_ATAC_BASE+0x08)
+#define ATAC_RESET             (MSR_ATAC_BASE+0x10)
+#define ATAC_CH0D0_PIO         (MSR_ATAC_BASE+0x20)
+#define ATAC_CH0D0_DMA         (MSR_ATAC_BASE+0x21)
+#define ATAC_CH0D1_PIO         (MSR_ATAC_BASE+0x22)
+#define ATAC_CH0D1_DMA         (MSR_ATAC_BASE+0x23) 
+#define ATAC_PCI_ABRTERR       (MSR_ATAC_BASE+0x24)
+#define ATAC_BM0_CMD_PRIM      0x00
+#define ATAC_BM0_STS_PRIM      0x02
+#define ATAC_BM0_PRD           0x04
+
+#define CS5535_CABLE_DETECT    0x48
+
+static unsigned int init_chipset_cs5535(struct pci_dev *, const char *);
+static void init_hwif_cs5535(ide_hwif_t *);
+
+static ide_pci_device_t cs5535_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "CS5535",
+		.init_chipset	= init_chipset_cs5535,
+		.init_iops	= NULL,
+		.init_hwif	= init_hwif_cs5535,
+		.channels	= 1,
+		.autodma	= AUTODMA,
+		.enablebits	= { {0x00,0x00,0x00} },  
+		.bootable	= ON_BOARD,
+		.extra		= 0,
+	}
+};
+
+#endif /* CS5535_H */
Index: linux-2.6.11/drivers/serial/Kconfig
===================================================================
--- linux-2.6.11.orig/drivers/serial/Kconfig
+++ linux-2.6.11/drivers/serial/Kconfig
@@ -572,6 +572,17 @@ config SERIAL_AU1X00_CONSOLE
 	  If you have an Alchemy AU1X00 processor (MIPS based) and you want
 	  to use a console on a serial port, say Y.  Otherwise, say N.
 
+config SERIAL_GEODE_UART2
+	bool "Enable AMD CS5535 UART2 as a serial port"
+	depends on MGEODE_GX || MGEODE_LX
+	default y
+	select SERIAL_CORE
+	help
+	  Select this to allow the user to select the secondary CS5535 UART 
+	  as a 16550 serial port instead of the default DDC interface. The
+	  UART2 can be selected by specifying geodeuart2 on the command
+	  line. 
+		
 config SERIAL_CORE
 	tristate
 
Index: linux-2.6.11/drivers/serial/Makefile
===================================================================
--- linux-2.6.11.orig/drivers/serial/Makefile
+++ linux-2.6.11/drivers/serial/Makefile
@@ -49,3 +49,4 @@ obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_si
 obj-$(CONFIG_SERIAL_MPSC) += mpsc.o
 obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o
 obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
+obj-$(CONFIG_SERIAL_GEODE_UART2) += cs5535_uart.o
Index: linux-2.6.11/drivers/serial/cs5535_uart.c
===================================================================
--- /dev/null
+++ linux-2.6.11/drivers/serial/cs5535_uart.c
@@ -0,0 +1,67 @@
+/*
+ * CS5535 UART2 driver 
+ * Copyright 2004, AMD
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/msr.h>
+#include <asm/io.h>
+
+/* The CS5535 companion chip has two UARTs.  This code enables the second
+   UART so other devices can use it.  We do it here so we can expose the
+   port early enough for serial debugging 
+*/
+
+/* Note - this does not check to see if the CS5535 actually exists */
+
+#define LO(b)  (((1 << b) << 16) | 0x0000)
+#define HI(b)  ((0x0000 << 16) | (1 << b))
+
+static u32 outtab[16] __initdata = 
+{ 
+	0x00,HI(4), 0x04,HI(4), 0x08,HI(4),
+	0x0c,LO(4), 0x10,HI(4), 0x14,LO(4),
+	0x18,LO(4), 0x1C,LO(4) 
+};
+
+static u32 intab[16] __initdata = {
+	0x20,HI(3), 0x24,LO(3), 0x28,LO(3),
+	0x2C,LO(3), 0x34,HI(3), 0x38,LO(3),
+     0x40,LO(3), 0x44,LO(3)
+};
+
+static int __init init_cs5535_uart2(char *str) 
+{
+	u32 lo = 0, hi = 0;
+	u32 base; u32 i;
+	
+	/* Enable UART2 instead of DDC */
+	
+	rdmsr(0x51400014, lo, hi);
+	lo &= 0xFF8FFFFF;
+	lo |= 0x00500000;   /* 0x2F8 ttyS1 */
+	wrmsr(0x51400014, lo, hi);
+	   
+	/* Set up the UART registers */
+	wrmsr(0x5140003E, 0x12, 0x00);
+	
+	rdmsr(0x5140000C, lo, hi); 
+	base = (u32)(lo & 0xFF00); 
+	
+	/* Enable the GPIO pins (in and out) */
+	
+	for(i = 0; i < 16; i += 2) {
+		outl(outtab[i + 1], base + outtab[i]);
+		outl(intab[i + 1], base + intab[i]);
+	}
+	
+	/* Enable the IRQ */
+	
+	rdmsr(0x51400021,lo,hi);
+	lo &= 0x0FFFFFFF;
+	lo |= 0x30000000; /* IRQ 3 */
+	wrmsr(0x51400021,lo,hi);
+}
+
+__setup("geodeuart2", init_cs5535_uart2);
Index: linux-2.6.11/drivers/usb/gadget/Kconfig
===================================================================
--- linux-2.6.11.orig/drivers/usb/gadget/Kconfig
+++ linux-2.6.11/drivers/usb/gadget/Kconfig
@@ -86,6 +86,37 @@ config USB_NET2280
 	depends on USB_GADGET_NET2280
 	default USB_GADGET
 
+config USB_GADGET_AMD5536UDC
+	boolean "AMD5536UDC"
+	depends on PCI || SOC_AU1200
+	select USB_GADGET_DUALSPEED
+	help
+	   AMD5536 UDC is a PCI based USB peripheral controller which
+	   supports both full and high speed USB 2.0 data transfers.  
+	   
+	   It has six configurable endpoints, as well as endpoint zero
+	   (for control transfers) and several endpoints with dedicated
+	   functions.
+
+	   Say "y" to link the driver statically, or "m" to build a
+	   dynamically linked module called "amd5536udc" and force all
+	   gadget drivers to also be dynamically linked.
+	   
+	   If the AMD5536UDC driver is configured to be statically
+	   linked this module will be linked into the kernel image
+	   as well otherwise two additional modules called "amd5536udc" 
+	   and "amd5536uoc" will be built.
+
+	   The AMD5536 USB device port can be used as
+	   either a host port or a device port depending on 
+	   the assignment within the BIOS setup.
+	   For more information, see Documentation/usb/amd5536uoc.txt
+
+config USB_AMD5536UDC
+	tristate
+	depends on USB_GADGET_AMD5536UDC
+	default USB_GADGET
+
 config USB_GADGET_PXA2XX
 	boolean "PXA 2xx or IXP 4xx"
 	depends on ARCH_PXA || ARCH_IXP4XX
@@ -399,4 +430,20 @@ config USB_G_SERIAL
 
 endchoice
 
+#
+# AMD5536 USB UOC options
+#
+
+config USB_GADGET_AMD5536UOC
+	boolean 
+	depends on USB_GADGET_AMD5536UDC
+	default USB_GADGET_AMD5536UDC
+
+config USB_AMD5536UOC
+	tristate
+	depends on USB_GADGET_AMD5536UOC
+	default USB_GADGET
+
 endmenu
+
+
Index: linux-2.6.11/drivers/usb/gadget/Makefile
===================================================================
--- linux-2.6.11.orig/drivers/usb/gadget/Makefile
+++ linux-2.6.11/drivers/usb/gadget/Makefile
@@ -3,6 +3,7 @@
 #
 obj-$(CONFIG_USB_DUMMY_HCD)	+= dummy_hcd.o
 obj-$(CONFIG_USB_NET2280)	+= net2280.o
+obj-$(CONFIG_USB_AMD5536UDC)	+= amd5536udc.o
 obj-$(CONFIG_USB_PXA2XX)	+= pxa2xx_udc.o
 obj-$(CONFIG_USB_GOKU)		+= goku_udc.o
 obj-$(CONFIG_USB_OMAP)		+= omap_udc.o
@@ -28,3 +29,8 @@ obj-$(CONFIG_USB_GADGETFS)	+= gadgetfs.o
 obj-$(CONFIG_USB_FILE_STORAGE)	+= g_file_storage.o
 obj-$(CONFIG_USB_G_SERIAL)	+= g_serial.o
 
+#
+# AMD5536 USB UOC options
+#
+obj-$(CONFIG_USB_AMD5536UOC)	+= amd5536uoc.o
+
Index: linux-2.6.11/drivers/usb/gadget/amd5536udc.c
===================================================================
--- /dev/null
+++ linux-2.6.11/drivers/usb/gadget/amd5536udc.c
@@ -0,0 +1,4786 @@
+/*
+ * AMD 5536 UDC high/full speed USB device controller.
+ */
+
+/*
+ * Copyright (C) 2005 AMD (http://www.amd.com)
+ * Author: Thomas Dahlmann 
+ *
+ * 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
+ */
+
+/*****************************************************************************
+ * Defines
+ *****************************************************************************/
+
+/* debug control */
+#undef UDC_DEBUG
+//DISABLEDamd #define UDC_DEBUG     1
+#undef UDC_VERBOSE
+//DISABLEDamd #define   UDC_VERBOSE         
+//DISABLEDamd #define UDC_REGISTER_DUMP
+
+/* device driver registration of kernel 2.6.x usage */
+//#define UDC_USE_DRIVER_REGISTER
+
+/* Driver strings */
+#define UDC_MOD_DESCRIPTION         "AMD 5536 UDC - USB Device Controller"
+#define UDC_DRIVER_VERSION_STRING   "01.00.0204 - $Revision: #13 $"
+
+/* kernel version of new gadget stack generation (for 2.6.x) */
+#define UDC_NEW_GADGET_KERNEL KERNEL_VERSION(2,5,59)
+
+/*****************************************************************************
+ *  Includes
+ *****************************************************************************/
+
+/* system */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/ioctl.h>
+#include <linux/fs.h>
+#if     LINUX_VERSION_CODE < UDC_NEW_GADGET_KERNEL
+#include <linux/wrapper.h>
+#else
+#include <linux/dmapool.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#endif
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/unaligned.h>
+
+/* MIPS config */
+#ifdef CONFIG_SOC_AU1200
+#if     LINUX_VERSION_CODE < UDC_NEW_GADGET_KERNEL
+#include <asm/au1000.h>
+#else
+#include <asm/mach-au1x00/au1000.h>
+#endif
+#ifndef CONFIG_USB_NON_PCI_OTGDEVICE
+#define CONFIG_USB_NON_PCI_OTGDEVICE
+#endif
+#endif
+
+/* gadget stack */
+#include <linux/usb_ch9.h>
+#include <linux/usb_gadget.h>
+#include <linux/usb_otg.h>
+
+/* udc specific */
+#include "amd5536udc.h"
+
+/* use RDE timer for new kernel only */
+#if   LINUX_VERSION_CODE >= UDC_NEW_GADGET_KERNEL
+#define UDC_USE_TIMER
+#endif
+/*****************************************************************************
+ *  Static Function Declarations
+ *****************************************************************************/
+
+void udc_tasklet_disconnect(unsigned long);
+#ifdef UDC_USE_TIMER
+void udc_timer_function(unsigned long v);
+void udc_pollstall_timer_function(unsigned long v);
+#endif
+static int udc_rxfifo_read_dwords(struct udc* dev, u32* buf, int dwords);
+static void empty_req_queue (struct udc_ep *);
+static int udc_probe (struct pci_dev *pdev, const struct pci_device_id *id);
+static void udc_remove (struct pci_dev *pdev);
+static void udc_basic_init (struct udc *dev);
+static void udc_setup_endpoints (struct udc *dev);
+static void udc_soft_reset(struct udc* dev);
+#ifdef UDC_DEBUG
+static void dump_buffer(u8* buf, u32 bytes);
+static int udc_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+static int udc_open (struct inode *inode, struct file *file);
+static int udc_release (struct inode *inode, struct file *file);
+#endif
+static struct udc_data_dma* udc_get_last_dma_desc(struct udc_request* req);
+static u32 udc_get_ppbdu_rxbytes(struct udc_request* req);
+static int udc_free_dma_chain(struct udc* dev, struct udc_request* req);
+static int udc_create_dma_chain(struct udc_ep* ep, struct udc_request* req, unsigned long buf_len, int gfp_flags);
+static inline int startup_registers(struct udc* dev);
+#ifdef CONFIG_SOC_AU1200
+void au1200_sync(void);
+#endif
+static int udc_remote_wakeup(struct udc* dev);
+#ifdef UDC_USE_DRIVER_REGISTER
+static int udc_suspend(struct udc* dev);
+static int udc_resume(struct udc* dev);
+#endif
+
+/*****************************************************************************
+ *  Data
+ *****************************************************************************/
+
+/* description */
+static const char mod_desc [] = UDC_MOD_DESCRIPTION;
+static const char name [] =     DRIVER_NAME_FOR_PRINT; 
+
+/* structure to hold endpoint function pointers */
+static struct usb_ep_ops udc_ep_ops;
+
+/* received setup data */
+static union udc_setup_data setup_data;
+
+/* pointer to device object */      
+static struct udc       *udc;
+
+/* irq spin lock for soft reset */
+spinlock_t udc_irq_spinlock;
+/* stall spin lock */
+spinlock_t udc_stall_spinlock;
+
+/* TODO this is used for dma chaining, global gfp not good */
+static int udc_gfp_flags = 0;
+        
+/* slave mode: pending bytes in rx fifo after nyet,
+used if EPIN irq came but no req was available */
+static unsigned int udc_rxfifo_pending = 0;
+
+/* count soft resets after suspend to avoid loop */
+static int soft_reset_occured = 0;
+#ifdef UDC_IPBUG_3958_WORKAROUND_SOFT_RESET_ON_USBRESET
+static int soft_reset_after_usbreset_occured = 0;
+#endif
+
+#ifdef UDC_USE_TIMER
+/* timer */
+static struct timer_list udc_timer;
+static int stop_timer = 0;
+int set_rde = -1;
+DECLARE_COMPLETION(on_exit);
+static struct timer_list udc_pollstall_timer;
+static int stop_pollstall_timer = 0;
+DECLARE_COMPLETION(on_pollstall_exit);
+#endif
+
+/* tasklet for usb disconnect */
+DECLARE_TASKLET(disconnect_tasklet, udc_tasklet_disconnect, (unsigned long) &udc);
+
+#ifdef CONFIG_USB_NON_PCI_OTGDEVICE
+static struct pci_dev pdev_dummy;
+static struct pci_dev* pdev = &pdev_dummy;
+#endif
+
+#ifdef UDC_IPBUG_3958_WORKAROUND
+/* CNAK pending field: bit0 = ep0in, bit16 = ep0out */
+static u32 cnak_pending = 0;
+#define UDC_QUEUE_CNAK(ep, num) \
+        if (readl(&((ep)->regs->ctl)) & AMD_BIT(UDC_EPCTL_NAK)) { \
+                DBG("NAK could not be cleared for ep%d\n", num); \
+                cnak_pending |= 1 << (num); \
+                (ep)->naking = 1; \
+        } \
+        else \
+                cnak_pending = cnak_pending & (~(1<<(num))); 
+#else
+#define UDC_QUEUE_CNAK(ep, num) {} 
+#endif
+#ifdef UDC_IPBUG_3958_WORKAROUND_RXFIFO_FLUSH
+/* rxfifo cleari/trash buffer */
+static u8 udc_rxfifo_trash[UDC_RXFIFO_SIZE];
+#endif
+
+#ifdef UDC_IPBUG_3943_WORKAROUND
+/* otg registering count */
+static u32 otg_reg_count = 0;
+#endif
+/* gadget registering count */
+static u32 gadget_bind_count = 0;
+
+/* endpoint names used for print */
+static const char ep0_string[] = "ep0in";
+static const char *ep_string[] = {
+        ep0_string,
+        "ep1in-int", "ep2in-bulk", "ep3in-bulk", "ep4in-bulk", "ep5in-bulk", "ep6in-bulk", "ep7in-bulk", "ep8in-bulk",
+        "ep9in-bulk", "ep10in-bulk", "ep11in-bulk", "ep12in-bulk", "ep13in-bulk", "ep14in-bulk", "ep15in-bulk", "ep0out",
+        "ep1out-bulk", "ep2out-bulk", "ep3out-bulk", "ep4out-bulk", "ep5out-bulk", "ep6out-bulk", "ep7out-bulk", "ep8out-bulk",
+        "ep9out-bulk", "ep10out-bulk", "ep11out-bulk", "ep12out-bulk", "ep13out-bulk", "ep14out-bulk", "ep15out-bulk" 
+};
+
+#ifdef UDC_DEBUG
+/* driver callback functions */
+static struct file_operations udc_fops = {
+        owner:          THIS_MODULE,
+
+        read:           NULL,
+        write:          NULL,
+        ioctl:          udc_ioctl,
+        open:           udc_open,
+        release:        udc_release,
+};
+#endif
+
+/* PCI device parameters */
+static struct pci_device_id pci_id[] = {{
+        .vendor =       UDC_PCI_VENID,
+        .device =       UDC_PCI_DEVID,
+        .class =        UDC_PCI_CLASS,
+        .class_mask =   UDC_PCI_CLASS_MASK,
+        .subvendor =    PCI_ANY_ID,
+        .subdevice =    PCI_ANY_ID,
+},
+{}
+};
+
+#ifndef CONFIG_USB_NON_PCI_OTGDEVICE
+/* PCI functions */
+static struct pci_driver udc_pci_driver = {
+        .name =         (char *) name,
+        .id_table =     pci_id,
+        .probe =        udc_probe,
+        .remove =       udc_remove,
+};
+#endif
+
+#ifdef UDC_DEBUG
+/* data for debuging only */
+static unsigned long no_pref_req = 0;
+static unsigned long no_req = 0;
+static u32 same_cfg = 0;
+static u32 num_enums = 0;
+#endif
+
+/****** following flags can be set by module parameters */
+/* DMA usage flag */
+static int use_dma = 1;
+/* packet per buffer dma */
+static int use_dma_ppb = 1;
+/* with per descr. update */
+static int use_dma_ppb_du = 0;
+/* buffer fill mode */
+static int use_dma_bufferfill_mode = 0;
+/* full speed only mode */
+static int use_fullspeed = 0;
+/* tx buffer size for high speed */
+static unsigned long hs_tx_buf = UDC_EPIN_BUFF_SIZE;
+
+/* module parameters */
+MODULE_PARM (use_dma, "i");
+MODULE_PARM_DESC (use_dma, "true for DMA");
+MODULE_PARM (use_dma_ppb, "i");
+MODULE_PARM_DESC (use_dma_ppb, "true for DMA in packet per buffer mode");
+MODULE_PARM (use_dma_ppb_du, "i");
+MODULE_PARM_DESC (use_dma_ppb_du, "true for DMA in packet per buffer mode with descriptor update");
+MODULE_PARM (use_fullspeed, "i");
+MODULE_PARM_DESC (use_fullspeed, "true for fullspeed only");
+MODULE_PARM (hs_tx_buf, "l");
+MODULE_PARM_DESC (hs_tx_buf, "high speed tx buffer size for data endpoints in dwords");
+
+MODULE_DESCRIPTION (UDC_MOD_DESCRIPTION);
+MODULE_AUTHOR ("Thomas Dahlmann");
+MODULE_LICENSE("GPL");
+
+#ifndef CONFIG_USB_NON_PCI_OTGDEVICE
+MODULE_DEVICE_TABLE (pci, pci_id);
+#endif
+
+/*****************************************************************************
+ *  Function Definitions
+ *****************************************************************************/
+
+/* AU specific */
+#ifdef CONFIG_SOC_AU1200
+void au1200_sync(void)
+{
+        au1200_sync_delay();
+}
+#endif
+
+#ifdef UDC_DEBUG
+/**
+ * Dumps byte read access
+ * 
+ * \param a address pointer
+ * \return read byte
+ */
+static void print_td(struct udc_data_dma *p)
+{
+        INFO("td = %08lx: status=%08lx bufptr=%08lx next=%08lx\n", 
+             (unsigned long) p,
+             (unsigned long) p->status,
+             (unsigned long) p->bufptr,
+             (unsigned long) p->next);
+}
+#endif
+
+/* printing registers --------------------------------------------------------*/
+/**
+ * Prints UDC device registers and endpoint irq registers
+ * 
+ * \param dev pointer to device struct 
+ */
+static void print_regs(struct udc* dev)
+{
+#ifndef UDC_IPBUG_3943_WORKAROUND
+        DBG( "------- Device registers -------\n");
+        DBG( "dev config     = %08lx\n", (unsigned long) dev->regs->cfg);
+        DBG( "dev control    = %08lx\n", (unsigned long) dev->regs->ctl);
+        DBG( "dev status     = %08lx\n", (unsigned long) dev->regs->sts);
+        DBG( "\n");
+        DBG( "dev int's      = %08lx\n", (unsigned long) dev->regs->irqsts);
+        DBG( "dev intmask    = %08lx\n", (unsigned long) dev->regs->irqmsk);
+        DBG( "\n");
+        DBG( "dev ep int's   = %08lx\n", (unsigned long) dev->regs->ep_irqsts);
+        DBG( "dev ep intmask = %08lx\n", (unsigned long) dev->regs->ep_irqmsk);
+        DBG( "\n");
+#endif
+        DBG( "USE DMA        = %d\n", use_dma);
+        if (use_dma && use_dma_ppb && !use_dma_ppb_du) {
+                DBG( "DMA mode       = PPBNDU (packet per buffer WITHOUT desc. update)\n");
+#ifndef UDC_DEBUG
+                INFO( "DMA mode (PPBNDU)\n");
+#endif
+        } 
+        else if (use_dma && use_dma_ppb_du && use_dma_ppb_du) {
+                DBG( "DMA mode       = PPBDU (packet per buffer WITH desc. update)\n");
+#ifndef UDC_DEBUG
+                INFO( "DMA mode (PPBDU)\n");
+#endif
+        } 
+        if (use_dma && use_dma_bufferfill_mode) {
+                DBG( "DMA mode       = BF (buffer fill mode)\n");
+#ifndef UDC_DEBUG
+                INFO( "DMA mode (BF)\n");
+#endif
+        } 
+#ifndef UDC_DEBUG
+        if (!use_dma) {
+                INFO( "FIFO mode\n");
+        } 
+#endif
+#ifdef UDC_USE_TIMER
+        INFO("RDE timer is used\n");
+#endif
+        DBG("-------------------------------------------------------\n");       
+}
+
+/**
+ * Prints snapshot of ep registers
+ * 
+ * \param dev   pointer to device struct
+ */
+#ifdef UDC_DEBUG
+static void print_ep_regs(struct udc* dev, struct udc_ep_regs* ep_regs)
+{
+        INFO( "ep control  = %08lx\n", (unsigned long) ep_regs->ctl);
+        INFO( "ep status   = %08lx\n", (unsigned long) ep_regs->sts);
+        INFO( "--------------------------------\n");
+}
+
+/* TODO tdahlman: remove */
+/**
+ * Prints misc information, to be removed
+ * 
+ * \param dev           pointer to device struct
+ */
+static void print_misc(struct udc* dev)
+{
+        print_regs(dev);
+ 
+        if (use_dma) {
+
+                INFO("no_req=%ld no_pref_req=%ld\n", no_req, no_pref_req);
+        }
+}
+#endif
+
+/* driver functions ----------------------------------------------------------*/
+/**
+ * Called by OS for insmod 
+ * 
+ * \param inode         file node
+ * \param               file struct
+ * \return read byte
+ */
+#ifdef UDC_DEBUG
+static int udc_open (struct inode *inode, struct file *file)
+{
+        int retval = 0;
+
+#if     LINUX_VERSION_CODE < UDC_NEW_GADGET_KERNEL
+        /* module use counter increment */
+        MOD_INC_USE_COUNT;
+#endif
+
+        return retval;
+}
+
+/**
+ * Called by OS for rmmod 
+ * 
+ * \param inode         file node
+ * \param file          file struct
+ * \return read byte
+ */
+static int udc_release (struct inode *inode, struct file *file)
+{
+        int retval = 0;
+
+#if     LINUX_VERSION_CODE < UDC_NEW_GADGET_KERNEL
+        /* module use counter decrement */
+        MOD_DEC_USE_COUNT;
+#endif
+        return retval;
+}
+
+/**
+ * Called by OS for ioctl() from user space
+ * 
+ * \param inode         file node
+ * \param file          file struct
+ * \param command       ioctl command code
+ * \param argument      ioctl argument
+ * \return 0 if success 
+ */
+static int udc_ioctl (struct inode *inode, 
+                      struct file *file, 
+                      unsigned int command,
+                      unsigned long argument)
+{
+        struct udc* dev = udc;
+        
+        if (!dev)
+                return -EINVAL;
+     
+        /* for testing PM */ 
+        switch (command)
+        {
+                case 1:
+                        udc_remote_wakeup(udc);
+                        break;
+                case 5:
+                        udc_suspend(udc);
+                        break;
+                case 6:
+                        udc_resume(udc);
+                        break;
+        }
+ 
+        INFO( "ioctl called\n");
+
+        //print_misc(dev);
+        return 0;
+}
+
+/**
+ *  Prints a buffers contents 
+ *  \param buf          pointer to buffer
+ *  \param bytes        number bytes to print
+ */
+static void dump_buffer(u8* buf, u32 bytes)
+{
+        int i;
+
+        printk("\nbuffer %lx = %d bytes:\n", (unsigned long) buf, bytes);
+        for (i = 0; i < bytes; i++) {
+                printk("%02x", *(buf + i));
+                if ((i+1)%16 == 0)
+                        printk("\n");
+        }
+        printk("\n");
+}
+#endif
+
+/**
+ * Masks unused interrupts 
+ * 
+ * \param dev           pointer to device struct
+ * \return 0 if success 
+ */
+static int udc_mask_unused_interrupts(struct udc* dev)
+{
+        u32 tmp;
+
+        /* mask all dev interrupts */
+        tmp =   AMD_BIT(UDC_DEVINT_SVC) |
+                AMD_BIT(UDC_DEVINT_ENUM) |
+                AMD_BIT(UDC_DEVINT_US) |
+                AMD_BIT(UDC_DEVINT_UR) |
+                AMD_BIT(UDC_DEVINT_ES) |
+                AMD_BIT(UDC_DEVINT_SI) |
+                AMD_BIT(UDC_DEVINT_SOF)|
+                AMD_BIT(UDC_DEVINT_SC);
+        writel(tmp, &dev->regs->irqmsk);        
+        
+        /* mask all ep interrupts */
+        writel(UDC_EPINT_MSK_DISABLE_ALL, &dev->regs->ep_irqmsk);        
+
+        return 0;
+}
+
+/**
+ * Enables endpoint 0 interrupts 
+ * 
+ * \param dev           pointer to device struct
+ * \return 0 if success 
+ */
+static int udc_enable_ep0_interrupts(struct udc* dev)
+{
+        u32 tmp;
+
+        DBG("udc_enable_ep0_interrupts()\n");
+
+        /* read irq mask */
+        tmp = readl(&dev->regs->ep_irqmsk);
+        /* enable ep0 irq's */
+        tmp &= AMD_UNMASK_BIT(UDC_EPINT_IN_EP0)
+               & AMD_UNMASK_BIT(UDC_EPINT_OUT_EP0);  
+        writel(tmp, &dev->regs->ep_irqmsk);        
+
+        return 0;
+}
+
+/**
+ * Enables device interrupts for SET_INTF and SET_CONFIG
+ * 
+ * \param dev           pointer to device struct
+ * \return 0 if success 
+ */
+static int udc_enable_dev_setup_interrupts(struct udc* dev)
+{
+        u32 tmp;
+
+        DBG("enable device interrupts for setup data\n");
+
+        /* read irq mask */
+        tmp = readl(&dev->regs->irqmsk);
+       
+        /* enable SET_INTERFACE, SET_CONFIG and other needed irq's */
+        tmp &= AMD_UNMASK_BIT(UDC_DEVINT_SI)
+               & AMD_UNMASK_BIT(UDC_DEVINT_SC)  
+               & AMD_UNMASK_BIT(UDC_DEVINT_UR)  
+#ifndef UDC_IPBUG_3943_WORKAROUND
+               & AMD_UNMASK_BIT(UDC_DEVINT_US)  
+#endif
+#ifndef UDC_IPBUG_3950_WORKAROUND
+               & AMD_UNMASK_BIT(UDC_DEVINT_SVC)
+#endif
+               & AMD_UNMASK_BIT(UDC_DEVINT_ENUM);
+        writel(tmp, &dev->regs->irqmsk);        
+
+        return 0;
+}
+
+/**
+ * Calculates fifo start of endpoint based on preceeding endpoints
+ * 
+ * \param ep           pointer to ep struct
+ * \return 0 if success 
+ */
+static int udc_set_txfifo_addr(struct udc_ep *ep)
+{
+        struct udc      *dev;
+        u32 tmp;
+        int i;
+
+        if (!ep || !(ep->in))
+                return -EINVAL;
+        
+        dev = ep->dev;
+        ep->txfifo = dev->txfifo;
+
+        /* traverse ep's */
+        for (i = 0; i < ep->num; i++) {
+                if (dev->ep[i].regs) {
+                        /* read fifo size */
+                        tmp = readl(&dev->ep[i].regs->bufin_framenum);
+                        tmp = AMD_GETBITS(tmp, UDC_EPIN_BUFF_SIZE);
+                        ep->txfifo+= tmp;
+                }
+        }
+        return 0;
+}
+
+/**
+ * Enables endpoint, is called by gadget driver
+ * 
+ * \param usbep         pointer to ep struct
+ * \param desc          pointer to endpoint descriptor
+ * \return 0 if success 
+ */
+static int
+udc_enable (struct usb_ep *usbep, const struct usb_endpoint_descriptor *desc)
+{
+        struct udc_ep           *ep;
+        struct udc              *dev;
+        u32                     tmp;
+        unsigned long           iflags;
+        u8 udc_csr_epix;
+
+        VDBG("udc_enable()\n");        
+        
+        ep = container_of (usbep, struct udc_ep, ep);
+        if (!usbep 
+            || usbep->name == ep0_string
+            || !desc 
+            || desc->bDescriptorType != USB_DT_ENDPOINT) {
+                ERR("udc_enable: !usbep=%d !desc=%d ep->desc!=NULL=%d usbep->name==ep0_string=%d desc->bDescriptorType!=USB_DT_ENDPOINT=%d\n",
+                     !usbep, !desc, ep->desc != NULL, usbep->name == ep0_string, desc->bDescriptorType != USB_DT_ENDPOINT);
+                return -EINVAL;
+        }
+        
+        DBG("udc_enable() ep %d\n", ep->num);
+
+        dev = ep->dev;
+
+        /* exit on suspend */
+        if (dev->sys_suspended) 
+              return -ESHUTDOWN;
+
+        if (!dev->driver
+            || dev->gadget.speed == USB_SPEED_UNKNOWN)
+                return -ESHUTDOWN;
+
+        spin_lock_irqsave (&dev->lock, iflags);
+        ep->desc = desc;
+
+        ep->halted = 0;
+
+        /* set traffic type */
+        tmp = readl(&dev->ep[ep->num].regs->ctl);
+        tmp = AMD_ADDBITS(tmp, desc->bmAttributes, UDC_EPCTL_ET);
+        writel(tmp, &dev->ep[ep->num].regs->ctl);
+
+        /* set max packet size */
+        tmp = readl(&dev->ep[ep->num].regs->bufout_maxpkt);
+        tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, UDC_EP_MAX_PKT_SIZE);
+        ep->ep.maxpacket = desc->wMaxPacketSize;
+        writel(tmp, &dev->ep[ep->num].regs->bufout_maxpkt);
+
+        /* IN ep */
+        if (ep->in) {
+                
+                /* ep ix in UDC CSR register space */
+                udc_csr_epix = ep->num;
+                
+                /* set buffer size (tx fifo entries) */
+                tmp = readl(&dev->ep[ep->num].regs->bufin_framenum);
+                /* double buffering: fifo size = 2 x max packet size */
+                tmp = AMD_ADDBITS(
+                              tmp,
+                              desc->wMaxPacketSize * UDC_EPIN_BUFF_SIZE_MULT /
+                                                     UDC_DWORD_BYTES,
+                              UDC_EPIN_BUFF_SIZE);                 
+                writel(tmp, &dev->ep[ep->num].regs->bufin_framenum);
+
+                /* calc. tx fifo base addr */
+                udc_set_txfifo_addr(ep); 
+
+                /* flush fifo */
+                tmp = readl(&ep->regs->ctl);
+                tmp |= AMD_BIT(UDC_EPCTL_F); 
+                writel(tmp, &ep->regs->ctl);
+                
+        } /* OUT ep */
+        else {
+                /* ep ix in UDC CSR register space */
+                udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS;
+
+                /* set max packet size UDC CSR  */
+                tmp = readl(&dev->csr->ne[ep->num - UDC_CSR_EP_OUT_IX_OFS]);
+                tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, UDC_CSR_NE_MAX_PKT);
+                writel(tmp, &dev->csr->ne[ep->num - UDC_CSR_EP_OUT_IX_OFS]);
+
+                if (ep->num != UDC_EP0OUT_IX) 
+                        dev->data_ep_enabled = 1;
+        }
+
+        /***** UDC CSR reg ****************************/
+        /* set ep values  */
+        tmp = readl(&dev->csr->ne[udc_csr_epix]);
+        /* max packet */
+        tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, UDC_CSR_NE_MAX_PKT);
+        /* ep number */
+        tmp = AMD_ADDBITS(tmp, desc->bEndpointAddress, UDC_CSR_NE_NUM);
+        /* ep direction */
+        tmp = AMD_ADDBITS(tmp, ep->in, UDC_CSR_NE_DIR);
+        /* ep type */
+        tmp = AMD_ADDBITS(tmp, desc->bmAttributes, UDC_CSR_NE_TYPE);
+        /* ep config */
+        tmp = AMD_ADDBITS(tmp, ep->dev->cur_config, UDC_CSR_NE_CFG);
+        /* ep interface */
+        tmp = AMD_ADDBITS(tmp, ep->dev->cur_intf, UDC_CSR_NE_INTF);
+        /* ep alt */
+        tmp = AMD_ADDBITS(tmp, ep->dev->cur_alt, UDC_CSR_NE_ALT);
+        /* write reg */
+        writel(tmp, &dev->csr->ne[udc_csr_epix]);
+        
+        /* enable ep irq */
+        tmp = readl(&dev->regs->ep_irqmsk);
+        tmp &= AMD_UNMASK_BIT(ep->num);
+        writel(tmp, &dev->regs->ep_irqmsk);        
+
+        /* clear NAK by writing CNAK */
+        /* avoid BNA for DMA,  dont clear NAK until DMA desc. written */
+        if (!use_dma) {
+                tmp = readl(&ep->regs->ctl);
+                tmp |= AMD_BIT(UDC_EPCTL_CNAK); 
+                writel(tmp, &ep->regs->ctl);
+                ep->naking = 0;
+                UDC_QUEUE_CNAK(ep, ep->num);
+        }
+        tmp = desc->bEndpointAddress;
+        DBG( "%s enabled\n",
+                usbep->name);
+
+        spin_unlock_irqrestore (&dev->lock, iflags);
+        return 0;
+}
+/**
+ * Resets endpoint
+ * 
+ * \param regs          pointer to device register struct
+ * \param ep            pointer to endpoint
+ */
+static void ep_init (struct udc_regs *regs, struct udc_ep *ep)
+{
+        u32             tmp;
+
+        VDBG("ep-%d reset\n", ep->num);
+        ep->desc = 0;
+        ep->ep.ops = &udc_ep_ops;
+        INIT_LIST_HEAD (&ep->queue);
+
+        ep->ep.maxpacket = (u16) ~0;
+        if (!(ep->dev->sys_suspended)) {
+                /* set NAK  */
+                tmp = readl(&ep->regs->ctl);
+                tmp |= AMD_BIT(UDC_EPCTL_SNAK); 
+                writel(tmp, &ep->regs->ctl);
+                ep->naking = 1;
+                
+                /* disable interrupt */
+                tmp = readl(&regs->ep_irqmsk);
+                tmp |= AMD_BIT(ep->num);
+                writel(tmp, &regs->ep_irqmsk);        
+
+                if (ep->in) {
+                        /* unset P and IN bit of potential former DMA */
+                        tmp = readl(&ep->regs->ctl);
+                        tmp &= AMD_UNMASK_BIT(UDC_EPCTL_P);
+                        writel(tmp, &ep->regs->ctl);
+
+                        tmp = readl(&ep->regs->sts);
+                        tmp |= AMD_BIT(UDC_EPSTS_IN);
+                        writel(tmp, &ep->regs->sts);
+
+                        /* flush the fifo */
+                        tmp = readl(&ep->regs->ctl);
+                        tmp |= AMD_BIT(UDC_EPCTL_F); 
+                        writel(tmp, &ep->regs->ctl);
+
+                }
+                /* reset desc pointer */
+                writel(0, &ep->regs->desptr);
+        }
+
+
+}
+
+/**
+ * Disables endpoint, is called by gadget driver
+ * 
+ * \param usbep            pointer to ep struct
+ * \return 0 if success 
+ */
+static int udc_disable (struct usb_ep *usbep)
+{
+        struct udc_ep   *ep = NULL;
+        unsigned long           iflags;
+
+        if (!usbep)
+                return -EINVAL;
+ 
+        ep = container_of (usbep, struct udc_ep, ep);
+        if (usbep->name == ep0_string
+            || !ep->desc)
+                return -EINVAL;
+
+        DBG("Disable ep-%d\n", ep->num);
+
+        spin_lock_irqsave(&ep->dev->lock, iflags);
+        empty_req_queue(ep);
+        ep_init(ep->dev->regs, ep);
+        spin_unlock_irqrestore(&ep->dev->lock, iflags);
+
+        return 0;
+}
+
+/**
+ * Allocates request packet, called by gadget driver
+ * 
+ * \param _ep           pointer to usb ep struct
+ * \param gfp_flags     flags for kmalloc
+ * \return allocated request packet, 0 if error
+ */
+static struct usb_request *
+udc_alloc_request (struct usb_ep *usbep, int gfp)
+{
+        struct udc_request      *req;
+        struct udc_data_dma     *dma_desc;
+        struct udc_ep   *ep;
+
+        VDBG("udc_alloc_req()\n");
+        if (!usbep)
+                return 0;
+
+        ep = container_of (usbep, struct udc_ep, ep);
+        /* TODO gfp flags used for dma chaining later - find better way */
+        udc_gfp_flags = gfp;
+
+        VDBG("udc_alloc_req(): ep%d\n", ep->num);
+        req = kmalloc (sizeof (struct udc_request), gfp);
+        if (!req)
+                return 0;
+
+        memset (req, 0, sizeof *req);
+        req->req.dma = DMA_DONT_USE;
+        INIT_LIST_HEAD (&req->queue);
+
+        if (ep->dma) {
+
+#if defined(CONFIG_MIPS)
+                gfp = GFP_ATOMIC | GFP_DMA;
+#endif
+                /* FIXME ep0 in requests are allocated from data pool here */
+                dma_desc = pci_pool_alloc (ep->dev->data_requests, gfp,
+                                           &req->td_phys);
+                if (!dma_desc) {
+                        kfree (req);
+                        return 0;
+                }
+
+                VDBG("udc_alloc_req: req = %lx dma_desc = %lx, req->td_phys = %lx\n",
+                     (unsigned long) req, (unsigned long) dma_desc, (unsigned long)req->td_phys);
+                /* prevent from using desc. - set HOST BUSY */
+                dma_desc->status = AMD_ADDBITS(dma_desc->status,
+                                          UDC_DMA_STP_STS_BS_HOST_BUSY,
+                                          UDC_DMA_STP_STS_BS);  
+                dma_desc->bufptr = __constant_cpu_to_le32 (DMA_DONT_USE);
+                req->td_data = dma_desc;
+                req->td_data_last = NULL;
+                req->chain_len = 1;
+        }
+
+        return &req->req;
+}
+
+/**
+ * Frees request packet, called by gadget driver
+ * 
+ * \param usbep   pointer to usb ep struct
+ * \param usbreq  pointer to request packet to be freed
+ */
+static void
+udc_free_request (struct usb_ep *usbep, struct usb_request *usbreq)
+{
+        struct udc_ep   *ep;
+        struct udc_request      *req;
+
+        if (!usbep || !usbreq)
+                return;
+
+        ep = container_of (usbep, struct udc_ep, ep);
+        req = container_of (usbreq, struct udc_request, req);
+        VDBG("free_req req=%lx\n", (unsigned long) req);
+        WARN_ON(!list_empty (&req->queue));
+        if (req->td_data) {
+                VDBG("req->td_data=%lx\n", (unsigned long) req->td_data);
+
+#ifdef UDC_IPDEFECT_9000004946_WORKAROUND
+                /* re-link broken chain  */
+                if (req->td_data_last) {
+                        req->td_data_last->next = req->td_data_last_next;
+                }
+#endif
+                /* free dma chain if created */
+                if (req->chain_len > 1) {
+                        udc_free_dma_chain(ep->dev, req);
+                }
+
+                pci_pool_free (ep->dev->data_requests, req->td_data, req->td_phys);
+        }
+        kfree (req);
+}
+
+/* choose dma buffer allocation method */
+#undef USE_KMALLOC
+#if     defined(CONFIG_X86)
+#define USE_KMALLOC
+/* FIXME TMP26: cached dma buffers seem no to work for 2.6.x to be
+ *  examined */
+#elif   defined(CONFIG_MIPS)
+/* MIPS kernel 2.4 */
+#if     LINUX_VERSION_CODE < UDC_NEW_GADGET_KERNEL 
+#if !defined(CONFIG_NONCOHERENT_IO)
+#define USE_KMALLOC
+#endif /* !defined(CONFIG_NONCOHERENT_IO) */
+#endif /* LINUX_VERSION_CODE < UDC_NEW_GADGET_KERNEL */
+#if   LINUX_VERSION_CODE >= UDC_NEW_GADGET_KERNEL
+#ifdef CONFIG_DMA_COHERENT
+#define USE_KMALLOC
+#endif /* CONFIG_DMA_COHERENT */
+#endif /* LINUX_VERSION_CODE >= UDC_NEW_GADGET_KERNEL */
+#endif
+
+/**
+ * Allocates data buffer for request packet, called by gadget driver
+ * 
+ * \param usbep         pointer to usb ep struct
+ * \param bytes         number bytes to allocate
+ * \param dma           pointer to dma struct
+ * \param gfp_flags     flags for allocate 
+ * \return pointer to allocated buffer, 0 if error
+ */
+static void *
+udc_alloc_buffer (
+        struct usb_ep           *usbep,
+        unsigned                len,
+        dma_addr_t              *dma,
+        int                     gfp
+)
+{
+        void            *ptr;
+        struct udc_ep   *ep;
+        VDBG("alloc_buffer(): %s\n", usbep->name);
+
+        ep = container_of (usbep, struct udc_ep, ep);
+        *dma = DMA_DONT_USE;
+
+        if (!usbep)
+                return 0;
+
+        if (ep->dma) {
+#if     defined(USE_KMALLOC)
+
+#if defined(CONFIG_MIPS)
+                gfp = GFP_ATOMIC | GFP_DMA;
+#endif
+                ptr = kmalloc(len, gfp);
+
+                if (ptr)
+                        *dma = virt_to_phys(ptr);
+
+#elif   LINUX_VERSION_CODE >= UDC_NEW_GADGET_KERNEL
+                ptr = dma_alloc_coherent (&ep->dev->pdev->dev, len, dma, gfp);
+#elif defined (CONFIG_MIPS)
+                ptr = pci_alloc_consistent(ep->dev->pdev, len, dma);
+#else
+#error no memory allocator
+#endif
+        } else
+                ptr = kmalloc(len, gfp);
+
+        VDBG("alloc_buffer() ptr = %lx dma=%lx\n", (unsigned long) ptr, (unsigned long) *dma);
+        return ptr;
+}
+
+
+/**
+ * Free data buffer for request packet, called by gadget driver
+ * 
+ * \param usbep         pointer to usb ep struct
+ * \param buf           pointer to buffer to be freed
+ * \param dma           pointer to dma struct
+ * \param len           number bytes to be freed 
+ * \return pointer to allocated buffer, 0 if error
+ */
+static void
+udc_free_buffer (
+        struct usb_ep *usbep,
+        void *buf,
+        dma_addr_t dma,
+        unsigned len
+) {
+        struct udc_ep   *ep;
+
+        VDBG ("ep %s - free buffer %lx\n", usbep->name, (unsigned long) buf);
+
+        /* null pointer ? */
+        if (!buf) {
+                return;
+        }
+
+        ep = container_of(usbep, struct udc_ep, ep);
+        if (!ep)
+                return;
+
+#ifndef USE_KMALLOC
+        if (dma != DMA_DONT_USE) {
+#if   LINUX_VERSION_CODE >= UDC_NEW_GADGET_KERNEL
+                dma_free_coherent (&ep->dev->pdev->dev, len, buf, dma);
+#else
+                pci_free_consistent(ep->dev->pdev, len, buf, dma);
+#endif
+        } else
+#endif
+        {
+                if (!(ep->dma))
+                        kfree (buf);
+        }
+
+}
+
+/**
+ * Write data to TX fifo for IN packets 
+ * 
+ * \param ep            pointer to ep struct
+ * \param req           pointer to request packet
+ * \return allocated request packet, 0 if error
+ */
+static void
+udc_txfifo_write (struct udc_ep *ep, struct usb_request *req)
+{
+        u8                      *req_buf;
+        u32                     *buf;
+        int i,j;
+        unsigned                bytes = 0;
+        unsigned                remaining = 0;
+
+        VDBG("udc_txfifo_write()\n");
+
+        if (!req || !ep)
+                return;
+
+        req_buf = req->buf + req->actual;
+        prefetch (req_buf);
+        remaining = req->length - req->actual;
+       
+        buf = (u32*) req_buf;        
+ 
+        bytes = ep->ep.maxpacket;
+        if (bytes > remaining)
+                bytes = remaining;
+	
+        /* dwords first */
+        for (i = 0; i < bytes / UDC_DWORD_BYTES; i++) {
+                writel(*(buf + i), ep->txfifo);
+        }
+
+        /* remaining bytes must be written by byte access */
+        for (j = 0; j < bytes % UDC_DWORD_BYTES; j++) {
+                writeb((u8) (*(buf + i) >> (j << UDC_BITS_PER_BYTE_SHIFT)),
+                       ep->txfifo);
+        }
+
+#ifdef UDC_IPBUG_2253_WORKAROUND
+        {
+                u32 tmp;
+
+                /* NAK if small packet until write confirm completed */
+                if (bytes < UDC_SMALL_PACKET) {
+                        /* set NAK */
+                        tmp = readl(&ep->regs->ctl);
+                        tmp |= AMD_BIT(UDC_EPCTL_SNAK); 
+                        writel(tmp, &ep->regs->ctl);
+                        ep->naking = 1;
+                        wb_flush();
+                }
+
+                /* dummy write confirm */
+                writel(0, &ep->regs->confirm); 
+
+                /* stop NAKing after small packet DMA */
+                if (ep->naking) {
+                        /* clear NAK by writing CNAK */
+                        tmp = readl(&ep->regs->ctl);
+                        tmp |= AMD_BIT(UDC_EPCTL_CNAK); 
+                        writel(tmp, &ep->regs->ctl);
+                        ep->naking = 0;
+                        UDC_QUEUE_CNAK(ep, ep->num);
+                }
+        }
+#else
+        /* dummy write confirm */
+        writel(0, &ep->regs->confirm); 
+#endif
+}
+
+/**
+ * Read dwords from RX fifo for OUT transfers
+ * 
+ * \param dev           pointer to device struct
+ * \param buf           pointer to buffer to be filled
+ * \param dwords        number of dwords to be read
+ * \return allocated request packet, 0 if error
+ */
+static int udc_rxfifo_read_dwords(struct udc* dev, u32* buf, int dwords)
+{
+        int i;
+        
+        VDBG("udc_read_dwords(): %d dwords\n", dwords);
+
+        for (i = 0; i < dwords; i++)
+        {
+                *(buf + i) = readl(dev->rxfifo);
+        }        
+        return 0;
+}
+
+/**
+ * Read bytes from RX fifo for OUT transfers
+ * 
+ * \param dev           pointer to device struct
+ * \param buf           pointer to buffer to be filled
+ * \param bytes         number of bytes to be read
+ * \return allocated request packet, 0 if error
+ */
+static int udc_rxfifo_read_bytes(struct udc* dev, u8* buf, int bytes)
+{
+        int i,j;
+        u32 tmp;
+        
+        VDBG("udc_read_bytes(): %d bytes\n", bytes);
+
+        /* dwords first */
+        for (i = 0; i < bytes / UDC_DWORD_BYTES; i++) {
+               *((u32*) (buf + (i<<2))) = readl(dev->rxfifo); 
+        }
+
+        /* remaining bytes must be read by byte access */
+        if (bytes % UDC_DWORD_BYTES) {
+                tmp = readl(dev->rxfifo);
+                for (j = 0; j < bytes % UDC_DWORD_BYTES; j++) {
+                        *(buf + (i<<2) + j) = (u8) (tmp & UDC_BYTE_MASK);
+                        tmp = tmp >> UDC_BITS_PER_BYTE;
+                }
+        }
+        
+        return 0;
+}
+
+/**
+ * Read data from RX fifo for OUT transfers
+ * 
+ * \param ep            pointer to ep struct
+ * \param req           pointer to request packet
+ * \return true if request completes for short or max packet, false otherwise   
+ */
+static int
+udc_rxfifo_read(struct udc_ep *ep, struct udc_request *req)
+{
+        u8 *buf;
+        unsigned buf_space;
+        unsigned bytes = 0; 
+        unsigned finished = 0;
+
+        /* received number bytes */
+        bytes = readl(&ep->regs->sts);
+        bytes = AMD_GETBITS(bytes, UDC_EPSTS_RX_PKT_SIZE);
+        
+        buf_space = req->req.length - req->req.actual;
+        buf = req->req.buf + req->req.actual;
+        if (bytes > buf_space) {
+                if ((buf_space % ep->ep.maxpacket) != 0) {
+                        ERR( "%s: received %d bytes, rx-buffer space =  %d bytes => buffer overrun\n",
+                                ep->ep.name, bytes, buf_space);
+                        req->req.status = -EOVERFLOW;
+                }
+                bytes = buf_space;
+        }
+        req->req.actual += bytes;
+
+        /* last packet ? */
+        if (((bytes % ep->ep.maxpacket) != 0)
+            || (!bytes)
+            || ((req->req.actual == req->req.length) && !req->req.zero))
+                finished = 1;
+
+        /* read rx fifo bytes */
+        VDBG("ep %s: rxfifo read %d bytes\n", ep->ep.name, bytes);
+        udc_rxfifo_read_bytes(ep->dev, buf, bytes); 
+        
+        return finished;
+}
+
+/**
+ * create/re-init a DMA descriptor or a DMA descriptor chain
+ *
+ * \param ep            pointer to endpoint struct 
+ * \param req           pointer to request packet
+ */
+static int prep_dma (struct udc_ep *ep, struct udc_request *req)
+{
+        int retval = 0;
+        u32                     tmp;
+        VDBG("prep_dma\n");
+        VDBG("prep_dma ep%d req->td_data=%lx\n",
+              ep->num, (unsigned long) req->td_data);
+
+        /* set buffer pointer */
+        req->td_data->bufptr   = req->req.dma;
+
+        /* set last bit */
+        req->td_data->status |= AMD_BIT(UDC_DMA_IN_STS_L);
+       
+        /* build/re-init dma chain if maxpkt scatter mode, not for EP0 */
+        if (use_dma_ppb && ep->num != UDC_EP0OUT_IX && ep->num != UDC_EP0IN_IX) {
+
+                retval = udc_create_dma_chain(ep, req, ep->ep.maxpacket, udc_gfp_flags);
+                if (retval != 0)
+                {
+                        if (retval == -ENOMEM)
+                                INFO("Out of DMA memory (allocation failed)\n");       
+                        return retval;
+                }
+                /*TODO better place ? */
+                if (ep->in) {
+                        if (req->req.length == ep->ep.maxpacket) {
+                                /* write tx bytes */
+                                req->td_data->status = AMD_ADDBITS(req->td_data->status,
+                                                ep->ep.maxpacket,
+                                                UDC_DMA_IN_STS_TXBYTES); 
+
+                        }
+                }
+                
+        }
+#ifdef UDC_IPDEFECT_9000004946_WORKAROUND
+        else { /* EP0 */
+                /* point to itself */
+                req->td_data->next = req->td_phys;
+        }
+#endif
+        
+        if (ep->in) {
+                VDBG("IN: use_dma_ppb=%d req->req.length=%d ep->ep.maxpacket=%d ep%d\n",
+                      use_dma_ppb, req->req.length, ep->ep.maxpacket, ep->num);
+                /* if bytes < max packet then tx bytes must */
+                /* be written in packet per buffer mode */
+                if (!use_dma_ppb || req->req.length < ep->ep.maxpacket
+                    || ep->num == UDC_EP0OUT_IX || ep->num == UDC_EP0IN_IX) {
+                        /* write tx bytes */
+                        req->td_data->status = AMD_ADDBITS(req->td_data->status,
+                                                            req->req.length,
+                                                            UDC_DMA_IN_STS_TXBYTES); 
+                        /* reset frame num */
+                        req->td_data->status = AMD_ADDBITS(req->td_data->status,
+                                                            0,
+                                                            UDC_DMA_IN_STS_FRAMENUM); 
+                }
+                /* set HOST BUSY */
+                req->td_data->status 
+                      = AMD_ADDBITS(req->td_data->status,
+                                    UDC_DMA_STP_STS_BS_HOST_BUSY,
+                                    UDC_DMA_STP_STS_BS);
+        }
+        else {
+                VDBG("OUT set host ready\n");
+                /* set HOST READY */
+                req->td_data->status 
+                      = AMD_ADDBITS(req->td_data->status,
+                                    UDC_DMA_STP_STS_BS_HOST_READY,
+                                    UDC_DMA_STP_STS_BS);
+
+ 
+                        /* clear NAK by writing CNAK */
+                        if (ep->naking) {
+                                tmp = readl(&ep->regs->ctl);
+                                tmp |= AMD_BIT(UDC_EPCTL_CNAK); 
+                                writel(tmp, &ep->regs->ctl);
+                                ep->naking = 0;
+                                UDC_QUEUE_CNAK(ep, ep->num);
+                        }
+
+        }
+
+        return retval;
+}
+
+/**
+ * Completes request packet 
+ * 
+ * \param ep            pointer to ep struct
+ * \param req           pointer to request packet
+ * \param sts           status of request
+ */
+static void
+complete_req(struct udc_ep *ep, struct udc_request *req, int sts)
+{
+        struct udc              *dev;
+        unsigned                halted;
+
+        VDBG("complete_req(): ep%d\n", ep->num);
+
+        dev = ep->dev;
+        /* unmap DMA */
+        if (req->dma_mapping) {
+                if (ep->in)
+                        pci_unmap_single(dev->pdev,
+                                         req->req.dma,
+                                         req->req.length,
+                                         PCI_DMA_TODEVICE);
+                else
+                        pci_unmap_single(dev->pdev,
+                                         req->req.dma,
+                                         req->req.length,
+                                         PCI_DMA_FROMDEVICE);
+                req->dma_mapping = 0;
+                req->req.dma = DMA_DONT_USE;
+        }
+
+        halted = ep->halted;
+        ep->halted = 1;
+
+        /* set new status if pending */
+        if (req->req.status == -EINPROGRESS)
+                req->req.status = sts;
+
+        /* remove from ep queue */
+        list_del_init (&req->queue);
+
+        VDBG( "req %p => complete %d bytes at %s with sts %d\n",
+                       &req->req, req->req.length, ep->ep.name, sts);
+        if (spin_is_locked(&dev->lock)) {
+                spin_unlock (&dev->lock);
+                req->req.complete (&ep->ep, &req->req);
+                spin_lock (&dev->lock);
+        }
+        else {
+                req->req.complete (&ep->ep, &req->req);
+        }
+        ep->halted = halted;
+}
+
+/**
+ * frees pci pool descriptors of a DMA chain 
+ * 
+ * \param dev           pointer to device struct
+ * \param req           pointer to request packet
+ * \return 0 if success
+ */
+static int udc_free_dma_chain(struct udc* dev, struct udc_request* req)
+{
+
+        int ret_val = 0;
+        struct udc_data_dma     *td;
+        struct udc_data_dma     *td_last = NULL;
+        unsigned int i;
+
+        DBG("free chain req = %lx\n", (unsigned long) req);
+
+#ifdef UDC_IPDEFECT_9000004946_WORKAROUND
+        /* re-link broken chain  */
+        if (req->td_data_last) {
+                req->td_data_last->next = req->td_data_last_next;
+        }
+#endif
+        /* do not free first desc., will be done by free for request */
+        td_last = req->td_data;
+#if defined (CONFIG_MIPS) && !defined(CONFIG_DMA_COHERENT)
+        td = UNCAC_ADDR(phys_to_virt(td_last->next));
+#else
+        td = phys_to_virt(td_last->next);
+#endif
+
+        for (i = 1; i < req->chain_len; i++) {
+
+                pci_pool_free (dev->data_requests, td,
+                                (dma_addr_t) td_last->next);
+                td_last = td;
+#if defined (CONFIG_MIPS) && !defined(CONFIG_DMA_COHERENT)
+                td = UNCAC_ADDR(phys_to_virt(td_last->next));
+#else
+                td = phys_to_virt(td_last->next);
+#endif
+        }
+
+#ifdef UDC_IPDEFECT_9000004946_WORKAROUND
+        req->td_data_last = NULL;
+#endif
+        return ret_val;        
+}
+
+/**
+ * Iterates to the end of a DMA chain and returns last descriptor 
+ * 
+ * \param req           pointer to request packet
+ * \return pointer to last descriptori of chain
+ */
+static struct udc_data_dma* udc_get_last_dma_desc(struct udc_request* req)
+{
+        struct udc_data_dma     *td;
+
+        td = req->td_data;
+        while (td && !(td->status & AMD_BIT(UDC_DMA_IN_STS_L))) {
+#if defined (CONFIG_MIPS) && !defined(CONFIG_DMA_COHERENT)
+                td = UNCAC_ADDR(phys_to_virt(td->next));
+#else
+                td = phys_to_virt(td->next);
+#endif
+        }
+
+        return td;
+
+}
+
+/**
+ * Iterates to the end of a DMA chain and counts bytes received 
+ * 
+ * \param req           pointer to request packet
+ * \return number of received bytes
+ */
+static u32 udc_get_ppbdu_rxbytes(struct udc_request* req)
+{
+        struct udc_data_dma     *td;
+        u32 count;
+
+        td = req->td_data;
+        /* received number bytes */
+        count = AMD_GETBITS(td->status, UDC_DMA_OUT_STS_RXBYTES); 
+        
+        while (td && !(td->status & AMD_BIT(UDC_DMA_IN_STS_L))) {
+#if defined (CONFIG_MIPS) && !defined(CONFIG_DMA_COHERENT)
+                td = UNCAC_ADDR(phys_to_virt(td->next));
+#else
+                td = phys_to_virt(td->next);
+#endif
+                /* received number bytes */
+                if (td) {
+                        count += AMD_GETBITS(td->status, UDC_DMA_OUT_STS_RXBYTES);
+                }
+        }
+
+        return count;
+
+}
+
+/**
+ * Creates or re-inits a DMA chain 
+ *
+ * \param ep            pointer to endpoint struct 
+ * \param req           pointer to request packet
+ * \param buf_len       number of buffer bytes per descriptor (except last short)
+ */
+static int udc_create_dma_chain(struct udc_ep* ep, struct udc_request* req, unsigned long buf_len, int gfp_flags)
+{
+        unsigned long bytes = req->req.length;
+        unsigned int i;
+        dma_addr_t dma_addr;
+        struct udc_data_dma     *td = NULL;
+        struct udc_data_dma     *last = NULL;
+        unsigned long txbytes;
+        unsigned create_new_chain = 0;
+        unsigned len;
+#ifdef UDC_IPDEFECT_9000004946_WORKAROUND
+        dma_addr_t last_next = DMA_DONT_USE;
+#endif
+
+        VDBG("udc_create_dma_chain: bytes=%ld buf_len=%ld\n", bytes, buf_len);
+        dma_addr = DMA_DONT_USE;
+
+        /* unset L bit in first desc for OUT */
+        if (!ep->in) {
+                req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L);
+        }
+        
+        /* alloc only new desc's if not already available */
+        len = req->req.length / ep->ep.maxpacket;
+        if (req->req.length % ep->ep.maxpacket) {
+                len++;
+        }
+
+        if (len > req->chain_len) {
+                /* shorter chain already allocated before */
+                if (req->chain_len > 1) {
+                        udc_free_dma_chain(ep->dev, req);
+                }
+                req->chain_len = len;
+                create_new_chain = 1;
+        }
+
+#ifdef UDC_IPDEFECT_9000004946_WORKAROUND
+        /* re-link broken chain  */
+        if (req->td_data_last) {
+                req->td_data_last->next = req->td_data_last_next;
+        }
+        /* if only one td then last_next is root td */
+        last_next = req->td_phys;
+#endif
+
+        td = req->td_data; 
+        /* gen. required number of descriptors and buffers */
+        for (i = buf_len; i < bytes; i += buf_len)
+        {
+                /* create or determine next desc. */
+                if (create_new_chain) {
+
+#if defined(CONFIG_MIPS)
+                        gfp_flags = GFP_ATOMIC | GFP_DMA;
+#endif
+                        td = pci_pool_alloc (ep->dev->data_requests, gfp_flags,
+                                             &dma_addr);
+                        if (!td) 
+                                return -ENOMEM;
+
+                        td->status = 0;
+                }
+                else if (i == buf_len)
+                {
+                        /* first td */
+#if defined (CONFIG_MIPS) && !defined(CONFIG_DMA_COHERENT)
+                        td = (struct udc_data_dma*) UNCAC_ADDR(phys_to_virt(req->td_data->next));
+#else
+                        td = (struct udc_data_dma*) phys_to_virt(req->td_data->next);
+#endif
+                        td->status = 0;
+                }
+                else {
+#if defined (CONFIG_MIPS) && !defined(CONFIG_DMA_COHERENT)
+                        td = (struct udc_data_dma*) UNCAC_ADDR(phys_to_virt(last->next));
+#else
+                        td = (struct udc_data_dma*) phys_to_virt(last->next);
+#endif
+                        td->status = 0;
+                }
+                        
+
+                if (td) {
+                        /* assign buffer */
+                       td->bufptr = req->req.dma + i; 
+                }
+                else {
+                        break;
+                }
+
+                /* short packet ? */
+                if ((bytes - i) >= buf_len) {
+                        txbytes = buf_len;
+                }
+                else {
+                        /* short packet */
+                        txbytes = bytes - i;
+                }
+         
+                /* link td and assign tx bytes */
+                if (i == buf_len) {
+                        if (create_new_chain) {
+                                req->td_data->next = dma_addr;
+                        }
+                        else {
+                                //req->td_data->next = virt_to_phys(td);
+                        }
+                        /* write tx bytes */
+                        if (ep->in) {
+                                /* first desc */
+                                req->td_data->status = AMD_ADDBITS(req->td_data->status,
+                                                                    ep->ep.maxpacket,
+                                                                    UDC_DMA_IN_STS_TXBYTES);
+                                /* second desc */
+                                td->status = AMD_ADDBITS(td->status,
+                                                          txbytes,
+                                                          UDC_DMA_IN_STS_TXBYTES); 
+                        } 
+
+#ifdef UDC_IPDEFECT_9000004946_WORKAROUND
+                        last_next = req->td_data->next;
+#endif
+                }
+                else {
+                        if (create_new_chain) {
+                                last->next = dma_addr;
+                        }
+                        else { 
+                                //last->next = virt_to_phys(td);
+                        }
+                        if (ep->in) {
+                                /* write tx bytes */
+                                td->status = AMD_ADDBITS(td->status,
+                                                          txbytes,
+                                                          UDC_DMA_IN_STS_TXBYTES); 
+                        }
+#ifdef UDC_IPDEFECT_9000004946_WORKAROUND
+                        last_next = last->next;
+#endif
+                }
+                last = td;
+        }
+        /* set last bit */
+        if (td) {
+                td->status |= AMD_BIT(UDC_DMA_IN_STS_L);
+                /* last desc. points to itself */
+#ifdef UDC_IPDEFECT_9000004946_WORKAROUND
+                /* remember broken chain next pointer */
+                req->td_data_last_next = td->next;
+                /* point to itself */
+                td->next = last_next;
+#endif
+                req->td_data_last = td;
+        }
+
+        return 0;
+}
+
+/**
+ * Enabling RX DMA  
+ *
+ * \param dev           pointer to UDC device object    
+ */
+static inline void udc_set_rde(struct udc* dev)
+{
+        u32 tmp;
+
+        VDBG("udc_set_rde()\n");
+#ifdef UDC_USE_TIMER
+        /* stop RDE timer */ 
+        if (timer_pending(&udc_timer)) {
+                set_rde = 0;
+                mod_timer(&udc_timer, jiffies - 1);
+        }
+#endif
+        /* set RDE */
+        tmp = readl(&dev->regs->ctl);
+        tmp |= AMD_BIT(UDC_DEVCTL_RDE);
+        writel(tmp, &dev->regs->ctl);                
+}
+
+/**
+ * Queues a request packet, called by gadget driver
+ * 
+ * \param usbep         pointer to usb ep struct
+ * \param usbreq        pointer to request packet to be freed
+ * \param gfp           flags for alloc
+ * \return 0 if success
+ */
+static int
+udc_queue (struct usb_ep *usbep, struct usb_request *usbreq, int gfp)
+{
+        int retval = 0;
+        unsigned long           iflags;
+        struct udc_ep   *ep;
+        struct udc_request      *req;
+        struct udc              *dev;
+        u32 tmp;
+        
+        VDBG ("udc_queue()\n");
+
+        /* check the inputs */
+        req = container_of (usbreq, struct udc_request, req);
+        VDBG("!usbep=%d !req=%d !buf=%d !compl=%d !empty_list=%d \n",
+                !usbep, !usbreq, !usbreq->buf, !usbreq->complete,
+                !list_empty(&req->queue));
+
+        if (!usbep || !usbreq || !usbreq->complete || !usbreq->buf
+                        || !list_empty (&req->queue))
+                return -EINVAL;
+
+        ep = container_of (usbep, struct udc_ep, ep);
+        if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX))
+                return -EINVAL;
+
+        VDBG("udc_queue(): ep%d-in=%d\n", ep->num, ep->in);
+        dev = ep->dev;
+
+        /* exit on suspend */
+        if (dev->sys_suspended) 
+              return -ESHUTDOWN;
+
+        if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
+                return -ESHUTDOWN;
+
+        /* map dma (usally done before) */
+        if (ep->dma && usbreq->length != 0 && usbreq->dma == DMA_DONT_USE) {
+                VDBG("DMA map req %lx\n", (unsigned long) req);
+                if (ep->in)
+                        usbreq->dma = pci_map_single(dev->pdev,
+                                                     usbreq->buf,
+                                                     usbreq->length,
+                                                     PCI_DMA_TODEVICE);
+                else
+                        usbreq->dma = pci_map_single(dev->pdev,
+                                                     usbreq->buf,
+                                                     usbreq->length,
+                                                     PCI_DMA_FROMDEVICE);
+                req->dma_mapping = 1;
+        }
+
+        VDBG( "%s queue req %p, len %d req->td_data=%lx buf %p\n",
+                        usbep->name, usbreq, usbreq->length, (unsigned long) req->td_data, usbreq->buf);
+
+        spin_lock_irqsave (&dev->lock, iflags);
+        usbreq->actual = 0;
+        usbreq->status = -EINPROGRESS;
+        req->dma_done = 0;
+        
+        /* on empty queue just do first transfer */
+        if (list_empty (&ep->queue)) {
+                /* zlp */
+                if (ep->in && usbreq->length == 0) {
+   