Merge branch 'upstream-jgarzik' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6 into upstream
diff --git a/Documentation/acpi-hotkey.txt b/Documentation/acpi-hotkey.txt
deleted file mode 100644
index 38040fa..0000000
--- a/Documentation/acpi-hotkey.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-driver/acpi/hotkey.c implement:
-1. /proc/acpi/hotkey/event_config 
-(event based hotkey or event config interface):
-a. add a  event based hotkey(event) : 
-echo "0:bus::action:method:num:num" > event_config
-
-b. delete a event based hotkey(event): 
-echo "1:::::num:num" > event_config
-
-c.  modify a event based hotkey(event):    
-echo "2:bus::action:method:num:num" > event_config
-
-2. /proc/acpi/hotkey/poll_config 
-(polling based hotkey or event config interface):
-a.add a polling based hotkey(event) : 	
-echo "0:bus:method:action:method:num" > poll_config
-this adding command will create a proc file 
-/proc/acpi/hotkey/method, which is used to get 
-result of polling.
-
-b.delete a polling based hotkey(event): 	
-echo "1:::::num" > event_config
-
-c.modify a polling based hotkey(event):    
-echo "2:bus:method:action:method:num" > poll_config
-
-3./proc/acpi/hotkey/action 
-(interface to call aml method associated with a 
-specific hotkey(event))
-echo "event_num:event_type:event_argument" > 
-	/proc/acpi/hotkey/action.
-The result of the execution of this aml method is 
-attached to /proc/acpi/hotkey/poll_method, which is dynamically
-created.  Please use command "cat /proc/acpi/hotkey/polling_method" 
-to retrieve it.
-
-Note: Use cmdline "acpi_generic_hotkey" to over-ride
-platform-specific with generic driver.
diff --git a/Documentation/arm/Samsung-S3C24XX/DMA.txt b/Documentation/arm/Samsung-S3C24XX/DMA.txt
new file mode 100644
index 0000000..37f4edc
--- /dev/null
+++ b/Documentation/arm/Samsung-S3C24XX/DMA.txt
@@ -0,0 +1,46 @@
+			S3C2410 DMA
+			===========
+
+Introduction
+------------
+
+   The kernel provides an interface to manage DMA transfers
+   using the DMA channels in the cpu, so that the central
+   duty of managing channel mappings, and programming the
+   channel generators is in one place.
+
+
+DMA Channel Ordering
+--------------------
+
+   Many of the range do not have connections for the DMA
+   channels to all sources, which means that some devices
+   have a restricted number of channels that can be used.
+
+   To allow flexibilty for each cpu type and board, the
+   dma code can be given an dma ordering structure which
+   allows the order of channel search to be specified, as
+   well as allowing the prohibition of certain claims.
+
+   struct s3c24xx_dma_order has a list of channels, and
+   each channel within has a slot for a list of dma
+   channel numbers. The slots are searched in order, for
+   the presence of a dma channel number with DMA_CH_VALID
+   orred in.
+
+   If the order has the flag DMA_CH_NEVER set, then after
+   checking the channel list, the system will return no
+   found channel, thus denying the request.
+
+   A board support file can call s3c24xx_dma_order_set()
+   to register an complete ordering set. The routine will
+   copy the data, so the original can be discared with
+   __initdata.
+
+
+Authour
+-------
+
+Ben Dooks,
+Copyright (c) 2007 Ben Dooks, Simtec Electronics
+Licensed under the GPL v2
diff --git a/Documentation/arm/Samsung-S3C24XX/Overview.txt b/Documentation/arm/Samsung-S3C24XX/Overview.txt
index 28d0147..c31b76f 100644
--- a/Documentation/arm/Samsung-S3C24XX/Overview.txt
+++ b/Documentation/arm/Samsung-S3C24XX/Overview.txt
@@ -8,13 +8,10 @@
 
   The Samsung S3C24XX range of ARM9 System-on-Chip CPUs are supported
   by the 's3c2410' architecture of ARM Linux. Currently the S3C2410,
-  S3C2440 and S3C2442 devices are supported.
+  S3C2412, S3C2413, S3C2440 and S3C2442 devices are supported.
 
   Support for the S3C2400 series is in progress.
 
-  Support for the S3C2412 and S3C2413 CPUs is being merged.
-
-
 Configuration
 -------------
 
@@ -26,6 +23,22 @@
   please check the machine specific documentation.
 
 
+Layout
+------
+
+  The core support files are located in the platform code contained in
+  arch/arm/plat-s3c24xx with headers in include/asm-arm/plat-s3c24xx.
+  This directory should be kept to items shared between the platform
+  code (arch/arm/plat-s3c24xx) and the arch/arm/mach-s3c24* code.
+
+  Each cpu has a directory with the support files for it, and the
+  machines that carry the device. For example S3C2410 is contained
+  in arch/arm/mach-s3c2410 and S3C2440 in arch/arm/mach-s3c2440
+
+  Register, kernel and platform data definitions are held in the
+  include/asm-arm/arch-s3c2410 directory.
+
+
 Machines
 --------
 
diff --git a/Documentation/driver-model/platform.txt b/Documentation/driver-model/platform.txt
index 9f0bc3b..f7c9262 100644
--- a/Documentation/driver-model/platform.txt
+++ b/Documentation/driver-model/platform.txt
@@ -66,7 +66,7 @@
 
 Device Enumeration
 ~~~~~~~~~~~~~~~~~~
-As a rule, platform specific (and often board-specific) setup code wil
+As a rule, platform specific (and often board-specific) setup code will
 register platform devices:
 
 	int platform_device_register(struct platform_device *pdev);
@@ -106,7 +106,7 @@
     * platform_device.id ... the device instance number, or else "-1"
       to indicate there's only one.
 
-These are catenated, so name/id "serial"/0 indicates bus_id "serial.0", and
+These are concatenated, so name/id "serial"/0 indicates bus_id "serial.0", and
 "serial/3" indicates bus_id "serial.3"; both would use the platform_driver
 named "serial".  While "my_rtc"/-1 would be bus_id "my_rtc" (no instance id)
 and use the platform_driver called "my_rtc".
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index c585aa8..6a451f4 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -253,29 +253,6 @@
 
 ---------------------------
 
-<<<<<<< test:Documentation/feature-removal-schedule.txt
-What:	ACPI hotkey driver (CONFIG_ACPI_HOTKEY)
-When:	2.6.21
-Why:	hotkey.c was an attempt to consolidate multiple drivers that use
-	ACPI to implement hotkeys.  However, hotkeys are not documented
-	in the ACPI specification, so the drivers used undocumented
-	vendor-specific hooks and turned out to be more different than
-	the same.
-
-	Further, the keys and the features supplied by each platform
-	are different, so there will always be a need for
-	platform-specific drivers.
-
-	So the new plan is to delete hotkey.c and instead, work on the
-	platform specific drivers to try to make them look the same
-	to the user when they supply the same features.
-
-	hotkey.c has always depended on CONFIG_EXPERIMENTAL
-
-Who:	Len Brown <len.brown@intel.com>
-
----------------------------
-
 What:	/sys/firmware/acpi/namespace
 When:	2.6.21
 Why:	The ACPI namespace is effectively the symbol list for
@@ -306,13 +283,6 @@
 
 ---------------------------
 
-What:	JFFS (version 1)
-When:	2.6.21
-Why:	Unmaintained for years, superceded by JFFS2 for years.
-Who:	Jeff Garzik <jeff@garzik.org>
-
----------------------------
-
 What:   sk98lin network driver
 When:   July 2007
 Why:    In kernel tree version of driver is unmaintained. Sk98lin driver
diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
index 4dc28cc..57178588 100644
--- a/Documentation/filesystems/00-INDEX
+++ b/Documentation/filesystems/00-INDEX
@@ -4,6 +4,8 @@
 	- explanation of how to make filesystems exportable.
 Locking
 	- info on locking rules as they pertain to Linux VFS.
+9p.txt
+	- 9p (v9fs) is an implementation of the Plan 9 remote fs protocol.
 adfs.txt
 	- info and mount options for the Acorn Advanced Disc Filing System.
 afs.txt
@@ -82,8 +84,6 @@
 	- info and mount options for the UDF filesystem.
 ufs.txt
 	- info on the ufs filesystem.
-v9fs.txt
-	- v9fs is a Unix implementation of the Plan 9 9p remote fs protocol.
 vfat.txt
 	- info on using the VFAT filesystem used in Windows NT and Windows 95
 vfs.txt
diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt
index 4d075a4..bbd8b28 100644
--- a/Documentation/filesystems/9p.txt
+++ b/Documentation/filesystems/9p.txt
@@ -40,6 +40,10 @@
   aname=name	aname specifies the file tree to access when the server is
   		offering several exported file systems.
 
+  cache=mode	specifies a cacheing policy.  By default, no caches are used.
+			loose = no attempts are made at consistency,
+                                intended for exclusive, read-only mounts
+
   debug=n	specifies debug level.  The debug level is a bitmask.
   			0x01 = display verbose error messages
 			0x02 = developer debug (DEBUG_CURRENT)
diff --git a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt
index 7ba2baa..5daa2aa 100644
--- a/Documentation/filesystems/sysfs-pci.txt
+++ b/Documentation/filesystems/sysfs-pci.txt
@@ -65,7 +65,7 @@
 ----------------------------------------
 
 Legacy I/O port and ISA memory resources are also provided in sysfs if the
-underlying platform supports them.  They're located in the PCI class heirarchy,
+underlying platform supports them.  They're located in the PCI class hierarchy,
 e.g.
 
 	/sys/class/pci_bus/0000:17/
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87
index 74a8099..c0528d6 100644
--- a/Documentation/hwmon/it87
+++ b/Documentation/hwmon/it87
@@ -135,6 +135,16 @@
 startup, consult lm_sensors's /etc/sensors.conf. (2 = thermistor;
 3 = thermal diode)
 
+
+Fan speed control
+-----------------
+
 The fan speed control features are limited to manual PWM mode. Automatic
 "Smart Guardian" mode control handling is not implemented. However
 if you want to go for "manual mode" just write 1 to pwmN_enable.
+
+If you are only able to control the fan speed with very small PWM values,
+try lowering the PWM base frequency (pwm1_freq). Depending on the fan,
+it may give you a somewhat greater control range. The same frequency is
+used to drive all fan outputs, which is why pwm2_freq and pwm3_freq are
+read-only.
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
index efef3b9..d73d2e8 100644
--- a/Documentation/hwmon/sysfs-interface
+++ b/Documentation/hwmon/sysfs-interface
@@ -166,16 +166,21 @@
 
 pwm[1-*]_enable
 		Switch PWM on and off.
-		Not always present even if fan*_pwm is.
+		Not always present even if pwmN is.
 		0: turn off
 		1: turn on in manual mode
 		2+: turn on in automatic mode
-		Check individual chip documentation files for automatic mode details.
+		Check individual chip documentation files for automatic mode
+		details.
 		RW
 
-pwm[1-*]_mode
-		0: DC mode
-		1: PWM mode
+pwm[1-*]_mode	0: DC mode (direct current)
+		1: PWM mode (pulse-width modulation)
+		RW
+
+pwm[1-*]_freq	Base PWM frequency in Hz.
+		Only possibly available when pwmN_mode is PWM, but not always
+		present even then.
 		RW
 
 pwm[1-*]_auto_channels_temp
diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf
index 8a15a74..030fac6 100644
--- a/Documentation/hwmon/w83627ehf
+++ b/Documentation/hwmon/w83627ehf
@@ -2,26 +2,29 @@
 =======================
 
 Supported chips:
-  * Winbond W83627EHF/EHG (ISA access ONLY)
+  * Winbond W83627EHF/EHG/DHG (ISA access ONLY)
     Prefix: 'w83627ehf'
     Addresses scanned: ISA address retrieved from Super I/O registers
-    Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf
+    Datasheet:
+        http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf
+        DHG datasheet confidential.
 
 Authors:
         Jean Delvare <khali@linux-fr.org>
         Yuan Mu (Winbond)
         Rudolf Marek <r.marek@assembler.cz>
+        David Hubbard <david.c.hubbard@gmail.com>
 
 Description
 -----------
 
-This driver implements support for the Winbond W83627EHF and W83627EHG
-super I/O chips. We will refer to them collectively as Winbond chips.
+This driver implements support for the Winbond W83627EHF, W83627EHG, and
+W83627DHG super I/O chips. We will refer to them collectively as Winbond chips.
 
 The chips implement three temperature sensors, five fan rotation
-speed sensors, ten analog voltage sensors, alarms with beep warnings (control
-unimplemented), and some automatic fan regulation strategies (plus manual
-fan control mode).
+speed sensors, ten analog voltage sensors (only nine for the 627DHG), alarms
+with beep warnings (control unimplemented), and some automatic fan regulation
+strategies (plus manual fan control mode).
 
 Temperatures are measured in degrees Celsius and measurement resolution is 1
 degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
@@ -55,6 +58,9 @@
 /sys files
 ----------
 
+name - this is a standard hwmon device entry. For the W83627EHF and W83627EHG,
+       it is set to "w83627ehf" and for the W83627DHG it is set to "w83627dhg"
+
 pwm[1-4] - this file stores PWM duty cycle or DC value (fan speed) in range:
 	   0 (stop) to 255 (full)
 
@@ -83,3 +89,37 @@
 
 Note: last two functions are influenced by other control bits, not yet exported
       by the driver, so a change might not have any effect.
+
+Implementation Details
+----------------------
+
+Future driver development should bear in mind that the following registers have
+different functions on the 627EHF and the 627DHG. Some registers also have
+different power-on default values, but BIOS should already be loading
+appropriate defaults. Note that bank selection must be performed as is currently
+done in the driver for all register addresses.
+
+0x49:  only on DHG, selects temperature source for AUX fan, CPU fan0
+0x4a:  not completely documented for the EHF and the DHG documentation assigns
+       different behavior to bits 7 and 6, including extending the temperature
+       input selection to SmartFan I, not just SmartFan III. Testing on the EHF
+       will reveal whether they are compatible or not.
+
+0x58:  Chip ID: 0xa1=EHF 0xc1=DHG
+0x5e:  only on DHG, has bits to enable "current mode" temperature detection and
+       critical temperature protection
+0x45b: only on EHF, bit 3, vin4 alarm (EHF supports 10 inputs, only 9 on DHG)
+0x552: only on EHF, vin4
+0x558: only on EHF, vin4 high limit
+0x559: only on EHF, vin4 low limit
+0x6b:  only on DHG, SYS fan critical temperature
+0x6c:  only on DHG, CPU fan0 critical temperature
+0x6d:  only on DHG, AUX fan critical temperature
+0x6e:  only on DHG, CPU fan1 critical temperature
+
+0x50-0x55 and 0x650-0x657 are marked "Test Register" for the EHF, but "Reserved
+       Register" for the DHG
+
+The DHG also supports PECI, where the DHG queries Intel CPU temperatures, and
+the ICH8 southbridge gets that data via PECI from the DHG, so that the
+southbridge drives the fans. And the DHG supports SST, a one-wire serial bus.
diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
index 4b3d671..bb5306e 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -34,7 +34,7 @@
 	   --- 6.1 Set variables to tweak the build to the architecture
 	   --- 6.2 Add prerequisites to archprepare:
 	   --- 6.3 List directories to visit when descending
-	   --- 6.4 Architecture specific boot images
+	   --- 6.4 Architecture-specific boot images
 	   --- 6.5 Building non-kbuild targets
 	   --- 6.6 Commands useful for building a boot image
 	   --- 6.7 Custom kbuild commands
@@ -124,7 +124,7 @@
 	Example:
 		obj-y += foo.o
 
-	This tell kbuild that there is one object in that directory, named
+	This tells kbuild that there is one object in that directory, named
 	foo.o. foo.o will be built from foo.c or foo.S.
 
 	If foo.o shall be built as a module, the variable obj-m is used.
@@ -353,7 +353,7 @@
 	Special rules are used when the kbuild infrastructure does
 	not provide the required support. A typical example is
 	header files generated during the build process.
-	Another example are the architecture specific Makefiles which
+	Another example are the architecture-specific Makefiles which
 	need special rules to prepare boot images etc.
 
 	Special rules are written as normal Make rules.
@@ -416,7 +416,7 @@
 		#arch/i386/kernel/Makefile
 		vsyscall-flags += $(call ld-option, -Wl$(comma)--hash-style=sysv)
 
-	In the above example vsyscall-flags will be assigned the option
+	In the above example, vsyscall-flags will be assigned the option
 	-Wl$(comma)--hash-style=sysv if it is supported by $(CC).
 	The second argument is optional, and if supplied will be used
 	if first argument is not supported.
@@ -434,7 +434,7 @@
 		#arch/i386/Makefile
 		cflags-y += $(call cc-option,-march=pentium-mmx,-march=i586)
 
-	In the above example cflags-y will be assigned the option
+	In the above example, cflags-y will be assigned the option
 	-march=pentium-mmx if supported by $(CC), otherwise -march=i586.
 	The second argument to cc-option is optional, and if omitted,
 	cflags-y will be assigned no value if first option is not supported.
@@ -750,10 +750,10 @@
    located at the root of the obj tree.
    The very first objects linked are listed in head-y, assigned by
    arch/$(ARCH)/Makefile.
-7) Finally, the architecture specific part does any required post processing
+7) Finally, the architecture-specific part does any required post processing
    and builds the final bootimage.
    - This includes building boot records
-   - Preparing initrd images and thelike
+   - Preparing initrd images and the like
 
 
 --- 6.1 Set variables to tweak the build to the architecture
@@ -880,7 +880,7 @@
 
 	$(head-y) lists objects to be linked first in vmlinux.
 	$(libs-y) lists directories where a lib.a archive can be located.
-	The rest lists directories where a built-in.o object file can be
+	The rest list directories where a built-in.o object file can be
 	located.
 
 	$(init-y) objects will be located after $(head-y).
@@ -888,7 +888,7 @@
 	$(core-y), $(libs-y), $(drivers-y) and $(net-y).
 
 	The top level Makefile defines values for all generic directories,
-	and arch/$(ARCH)/Makefile only adds architecture specific directories.
+	and arch/$(ARCH)/Makefile only adds architecture-specific directories.
 
 	Example:
 		#arch/sparc64/Makefile
@@ -897,7 +897,7 @@
 		drivers-$(CONFIG_OPROFILE)  += arch/sparc64/oprofile/
 
 
---- 6.4 Architecture specific boot images
+--- 6.4 Architecture-specific boot images
 
 	An arch Makefile specifies goals that take the vmlinux file, compress
 	it, wrap it in bootstrapping code, and copy the resulting files
@@ -924,7 +924,7 @@
 	"$(Q)$(MAKE) $(build)=<dir>" is the recommended way to invoke
 	make in a subdirectory.
 
-	There are no rules for naming architecture specific targets,
+	There are no rules for naming architecture-specific targets,
 	but executing "make help" will list all relevant targets.
 	To support this, $(archhelp) must be defined.
 
@@ -982,7 +982,7 @@
 			$(call if_changed,ld/objcopy/gzip)
 
 	When the rule is evaluated, it is checked to see if any files
-	needs an update, or the command line has changed since the last
+	need an update, or the command line has changed since the last
 	invocation. The latter will force a rebuild if any options
 	to the executable have changed.
 	Any target that utilises if_changed must be listed in $(targets),
@@ -1089,7 +1089,7 @@
 	                  assignment.
 
 	The kbuild infrastructure for *lds file are used in several
-	architecture specific files.
+	architecture-specific files.
 
 
 === 7 Kbuild Variables
@@ -1133,7 +1133,7 @@
 
 	This variable defines a place for the arch Makefiles to install
 	the resident kernel image and System.map file.
-	Use this for architecture specific install targets.
+	Use this for architecture-specific install targets.
 
     INSTALL_MOD_PATH, MODLIB
 
diff --git a/Documentation/kernel-docs.txt b/Documentation/kernel-docs.txt
index b53bccb..c68dafe 100644
--- a/Documentation/kernel-docs.txt
+++ b/Documentation/kernel-docs.txt
@@ -1,10 +1,10 @@
 
-       Index of Documentation for People Interested in Writing and/or
-                                      
-                      Understanding the Linux Kernel.
-                                      
-               Juan-Mariano de Goyeneche <jmseyas@dit.upm.es>
-                                      
+    Index of Documentation for People Interested in Writing and/or
+
+                   Understanding the Linux Kernel.
+
+          Juan-Mariano de Goyeneche <jmseyas@dit.upm.es>
+
 /*
  * The latest version of this document may be found at:
  *   http://www.dit.upm.es/~jmseyas/linux/kernel/hackers-docs.html
@@ -61,18 +61,18 @@
        13.-The Linux Kernel Sources, A.-Linux Data Structures, B.-The
        Alpha AXP Processor, C.-Useful Web and FTP Sites, D.-The GNU
        General Public License, Glossary". In short: a must have.
-       
-     * Title: "The Linux Kernel Hackers' Guide"
-       Author: Michael K.Johnson and others.
-       URL: http://www.tldp.org/LDP/khg/HyperNews/get/khg.html
-       Keywords: everything!
-       Description: No more Postscript book-like version. Only HTML now.
-       Many people have contributed. The interface is similar to web
-       available mailing lists archives. You can find some articles and
-       then some mails asking questions about them and/or complementing
-       previous contributions. A little bit anarchic in this aspect, but
-       with some valuable information in some cases.
-       
+
+     * Title: "Linux Device Drivers, 2nd Edition"
+       Author: Alessandro Rubini and Jonathan Corbet.
+       URL: http://www.xml.com/ldd/chapter/book/index.html
+       Keywords: device drivers, modules, debugging, memory, hardware,
+       interrupt handling, char drivers, block drivers, kmod, mmap, DMA,
+       buses.
+       Description: O'Reilly's popular book, now also on-line under the
+       GNU Free Documentation License.
+       Notes: You can also buy it in paper-form from O'Reilly. See below
+       under BOOKS (Not on-line).
+
      * Title: "Conceptual Architecture of the Linux Kernel"
        Author: Ivan T. Bowman.
        URL: http://plg.uwaterloo.ca/~itbowman/papers/CS746G-a1.html
@@ -81,17 +81,17 @@
        Description: Conceptual software arquitecture of the Linux kernel,
        automatically extracted from the source code. Very detailed. Good
        figures. Gives good overall kernel understanding.
-       
+
      * Title: "Concrete Architecture of the Linux Kernel"
        Author: Ivan T. Bowman, Saheem Siddiqi, and Meyer C. Tanuan.
        URL: http://plg.uwaterloo.ca/~itbowman/papers/CS746G-a2.html
-       Keywords: concrete arquitecture, extracted design, reverse
+       Keywords: concrete architecture, extracted design, reverse
        engineering, system structure, dependencies.
-       Description: Concrete arquitecture of the Linux kernel,
+       Description: Concrete architecture of the Linux kernel,
        automatically extracted from the source code. Very detailed. Good
        figures. Gives good overall kernel understanding. This papers
        focus on lower details than its predecessor (files, variables...).
-       
+
      * Title: "Linux as a Case Study: Its Extracted Software
        Architecture"
        Author: Ivan T. Bowman, Richard C. Holt and Neil V. Brewster.
@@ -101,7 +101,7 @@
        Description: Paper appeared at ICSE'99, Los Angeles, May 16-22,
        1999. A mixture of the previous two documents from the same
        author.
-       
+
      * Title: "Overview of the Virtual File System"
        Author: Richard Gooch.
        URL: http://www.atnf.csiro.au/~rgooch/linux/vfs.txt
@@ -111,20 +111,20 @@
        What is it, how it works, operations taken when opening a file or
        mounting a file system and description of important data
        structures explaining the purpose of each of their entries.
-       
+
      * Title: "The Linux RAID-1, 4, 5 Code"
        Author: Ingo Molnar, Gadi Oxman and Miguel de Icaza.
-       URL: http://www2.linuxjournal.com/lj-issues/issue44/2391.html
+       URL: http://www.linuxjournal.com/article.php?sid=2391
        Keywords: RAID, MD driver.
        Description: Linux Journal Kernel Korner article. Here is it's
        abstract: "A description of the implementation of the RAID-1,
        RAID-4 and RAID-5 personalities of the MD device driver in the
        Linux kernel, providing users with high performance and reliable,
        secondary-storage capability using software".
-       
+
      * Title: "Dynamic Kernels: Modularized Device Drivers"
        Author: Alessandro Rubini.
-       URL: http://www2.linuxjournal.com/lj-issues/issue23/1219.html
+       URL: http://www.linuxjournal.com/article.php?sid=1219
        Keywords: device driver, module, loading/unloading modules,
        allocating resources.
        Description: Linux Journal Kernel Korner article. Here is it's
@@ -134,10 +134,10 @@
        loadable modules. This installment presents an introduction to the
        topic, preparing the reader to understand next month's
        installment".
-       
+
      * Title: "Dynamic Kernels: Discovery"
        Author: Alessandro Rubini.
-       URL: http://www2.linuxjournal.com/lj-issues/issue24/1220.html
+       URL: http://www.linuxjournal.com/article.php?sid=1220
        Keywords: character driver, init_module, clean_up module,
        autodetection, mayor number, minor number, file operations,
        open(), close().
@@ -146,20 +146,20 @@
        the actual code to create custom module implementing a character
        device driver. It describes the code for module initialization and
        cleanup, as well as the open() and close() system calls".
-       
+
      * Title: "The Devil's in the Details"
        Author: Georg v. Zezschwitz and Alessandro Rubini.
-       URL: http://www2.linuxjournal.com/lj-issues/issue25/1221.html
+       URL: http://www.linuxjournal.com/article.php?sid=1221
        Keywords: read(), write(), select(), ioctl(), blocking/non
        blocking mode, interrupt handler.
        Description: Linux Journal Kernel Korner article. Here is it's
        abstract: "This article, the third of four on writing character
        device drivers, introduces concepts of reading, writing, and using
        ioctl-calls".
-       
+
      * Title: "Dissecting Interrupts and Browsing DMA"
        Author: Alessandro Rubini and Georg v. Zezschwitz.
-       URL: http://www2.linuxjournal.com/lj-issues/issue26/1222.html
+       URL: http://www.linuxjournal.com/article.php?sid=1222
        Keywords: interrupts, irqs, DMA, bottom halves, task queues.
        Description: Linux Journal Kernel Korner article. Here is it's
        abstract: "This is the fourth in a series of articles about
@@ -170,10 +170,10 @@
        writing, and several different facilities have been provided for
        different situations. We also investigate the complex topic of
        DMA".
-       
+
      * Title: "Device Drivers Concluded"
        Author: Georg v. Zezschwitz.
-       URL: http://www2.linuxjournal.com/lj-issues/issue28/1287.html
+       URL: http://www.linuxjournal.com/article.php?sid=1287
        Keywords: address spaces, pages, pagination, page management,
        demand loading, swapping, memory protection, memory mapping, mmap,
        virtual memory areas (VMAs), vremap, PCI.
@@ -182,10 +182,10 @@
        five articles about character device drivers. In this final
        section, Georg deals with memory mapping devices, beginning with
        an overall description of the Linux memory management concepts".
-       
+
      * Title: "Network Buffers And Memory Management"
        Author: Alan Cox.
-       URL: http://www2.linuxjournal.com/lj-issues/issue30/1312.html
+       URL: http://www.linuxjournal.com/article.php?sid=1312
        Keywords: sk_buffs, network devices, protocol/link layer
        variables, network devices flags, transmit, receive,
        configuration, multicast.
@@ -214,28 +214,26 @@
        of the Coda filesystem. This version document is meant to describe
        the current interface (version 1.0) as well as improvements we
        envisage".
-       
+
      * Title: "Programming PCI-Devices under Linux"
        Author: Claus Schroeter.
        URL:
-       ftp://ftp.llp.fu-berlin.de/pub/linux/LINUX-LAB/whitepapers/pcip.ps
-       .gz
+       ftp://ftp.llp.fu-berlin.de/pub/linux/LINUX-LAB/whitepapers/pcip.ps.gz
        Keywords: PCI, device, busmastering.
        Description: 6 pages tutorial on PCI programming under Linux.
        Gives the basic concepts on the architecture of the PCI subsystem,
        as long as basic functions and macros to read/write the devices
        and perform busmastering.
-       
+
      * Title: "Writing Character Device Driver for Linux"
        Author: R. Baruch and C. Schroeter.
        URL:
-       ftp://ftp.llp.fu-berlin.de/pub/linux/LINUX-LAB/whitepapers/drivers
-       .ps.gz
+       ftp://ftp.llp.fu-berlin.de/pub/linux/LINUX-LAB/whitepapers/drivers.ps.gz
        Keywords: character device drivers, I/O, signals, DMA, accessing
        ports in user space, kernel environment.
        Description: 68 pages paper on writing character drivers. A little
        bit old (1.993, 1.994) although still useful.
-       
+
      * Title: "Design and Implementation of the Second Extended
        Filesystem"
        Author: Rémy Card, Theodore Ts'o, Stephen Tweedie.
@@ -249,14 +247,14 @@
        e2fsck's passes description... A must read!
        Notes: This paper was first published in the Proceedings of the
        First Dutch International Symposium on Linux, ISBN 90-367-0385-9.
-       
+
      * Title: "Analysis of the Ext2fs structure"
        Author: Louis-Dominique Dubeau.
-       URL: http://step.polymtl.ca/~ldd/ext2fs/ext2fs_toc.html
+       URL: http://www.nondot.org/sabre/os/files/FileSystems/ext2fs/
        Keywords: ext2, filesystem, ext2fs.
        Description: Description of ext2's blocks, directories, inodes,
        bitmaps, invariants...
-       
+
      * Title: "Journaling the Linux ext2fs Filesystem"
        Author: Stephen C. Tweedie.
        URL:
@@ -265,7 +263,7 @@
        Description: Excellent 8-pages paper explaining the journaling
        capabilities added to ext2 by the author, showing different
        problems faced and the alternatives chosen.
-       
+
      * Title: "Kernel API changes from 2.0 to 2.2"
        Author: Richard Gooch.
        URL:
@@ -273,7 +271,7 @@
        Keywords: 2.2, changes.
        Description: Kernel functions/structures/variables which changed
        from 2.0.x to 2.2.x.
-       
+
      * Title: "Kernel API changes from 2.2 to 2.4"
        Author: Richard Gooch.
        URL:
@@ -345,17 +343,7 @@
        Notes: Beware: the main page states: "This document may not be
        published, printed or used in excerpts without explicit permission
        of the author". Fortunately, it may still be read...
-       
-     * Title: "Tour Of the Linux Kernel Source"
-       Author: Vijo Cherian.
-       URL: http://www.geocities.com/vijoc/tolks/tolks.html
-       Keywords: .
-       Description: A classic of this page! Was lost for a while and is
-       back again. Thanks Vijo! TOLKS: the name says it all. A tour of
-       the sources, describing directories, files, variables, data
-       structures... It covers general stuff, device drivers,
-       filesystems, IPC and Networking Code.
-       
+
      * Title: "Linux Kernel Mailing List Glossary"
        Author: various
        URL: http://kernelnewbies.org/glossary/
@@ -377,7 +365,17 @@
        kernels, but most of it applies to 2.2 too; 2.0 is slightly
        different". Freely redistributable under the conditions of the GNU
        General Public License.
-       
+
+     * Title: "Global spinlock list and usage"
+       Author: Rick Lindsley.
+       URL: http://lse.sourceforge.net/lockhier/global-spin-lock
+       Keywords: spinlock.
+       Description: This is an attempt to document both the existence and
+       usage of the spinlocks in the Linux 2.4.5 kernel. Comprehensive
+       list of spinlocks showing when they are used, which functions
+       access them, how each lock is acquired, under what conditions it
+       is held, whether interrupts can occur or not while it is held...
+
      * Title: "Porting Linux 2.0 Drivers To Linux 2.2: Changes and New
        Features "
        Author: Alan Cox.
@@ -385,70 +383,70 @@
        Keywords: ports, porting.
        Description: Article from Linux Magazine on porting from 2.0 to
        2.2 kernels.
-       
+
      * Title: "Porting Device Drivers To Linux 2.2: part II"
        Author: Alan Cox.
        URL: http://www.linux-mag.com/1999-06/gear_01.html
        Keywords: ports, porting.
        Description: Second part on porting from 2.0 to 2.2 kernels.
-       
+
      * Title: "How To Make Sure Your Driver Will Work On The Power
        Macintosh"
        Author: Paul Mackerras.
        URL: http://www.linux-mag.com/1999-07/gear_01.html
        Keywords: Mac, Power Macintosh, porting, drivers, compatibility.
        Description: The title says it all.
-       
+
      * Title: "An Introduction to SCSI Drivers"
        Author: Alan Cox.
        URL: http://www.linux-mag.com/1999-08/gear_01.html
        Keywords: SCSI, device, driver.
        Description: The title says it all.
-       
+
      * Title: "Advanced SCSI Drivers And Other Tales"
        Author: Alan Cox.
        URL: http://www.linux-mag.com/1999-09/gear_01.html
        Keywords: SCSI, device, driver, advanced.
        Description: The title says it all.
-       
+
      * Title: "Writing Linux Mouse Drivers"
        Author: Alan Cox.
        URL: http://www.linux-mag.com/1999-10/gear_01.html
        Keywords: mouse, driver, gpm.
        Description: The title says it all.
-       
+
      * Title: "More on Mouse Drivers"
        Author: Alan Cox.
        URL: http://www.linux-mag.com/1999-11/gear_01.html
        Keywords: mouse, driver, gpm, races, asynchronous I/O.
        Description: The title still says it all.
-       
+
      * Title: "Writing Video4linux Radio Driver"
        Author: Alan Cox.
        URL: http://www.linux-mag.com/1999-12/gear_01.html
        Keywords: video4linux, driver, radio, radio devices.
        Description: The title says it all.
-       
+
      * Title: "Video4linux Drivers, Part 1: Video-Capture Device"
        Author: Alan Cox.
        URL: http://www.linux-mag.com/2000-01/gear_01.html
        Keywords: video4linux, driver, video capture, capture devices,
        camera driver.
        Description: The title says it all.
-       
+
      * Title: "Video4linux Drivers, Part 2: Video-capture Devices"
        Author: Alan Cox.
        URL: http://www.linux-mag.com/2000-02/gear_01.html
        Keywords: video4linux, driver, video capture, capture devices,
        camera driver, control, query capabilities, capability, facility.
        Description: The title says it all.
-       
+
      * Title: "PCI Management in Linux 2.2"
        Author: Alan Cox.
        URL: http://www.linux-mag.com/2000-03/gear_01.html
        Keywords: PCI, bus, bus-mastering.
        Description: The title says it all.
-       
+
      * Title: "Linux 2.4 Kernel Internals"
        Author: Tigran Aivazian and Christoph Hellwig.
        URL: http://www.moses.uklinux.net/patches/lki.html
@@ -456,13 +454,11 @@
        Description: A little book used for a short training course.
        Covers building the kernel image, booting (including SMP bootup),
        process management, VFS and more.
-       
+
      * Title: "Linux IP Networking. A Guide to the Implementation and
        Modification of the Linux Protocol Stack."
        Author: Glenn Herrin.
-       URL:
-       http://kernelnewbies.org/documents/ipnetworking/linuxipnetworking.
-       html
+       URL: http://www.cs.unh.edu/cnrg/gherrin
        Keywords: network, networking, protocol, IP, UDP, TCP, connection,
        socket, receiving, transmitting, forwarding, routing, packets,
        modules, /proc, sk_buff, FIB, tags.
@@ -495,7 +491,7 @@
        drivers for the Linux PCMCIA Card Services interface. It also
        describes how to write user-mode utilities for communicating with
        Card Services.
-       
+
      * Title: "The Linux Kernel NFSD Implementation"
        Author: Neil Brown.
        URL:
@@ -591,47 +587,22 @@
        Pages: 520.
        ISBN: 2-212-08932-5
        Notes: French.
-       
-     * Title: "The Linux Kernel Book"
-       Author: Remy Card, Eric Dumas, Franck Mevel.
-       Publisher: John Wiley & Sons.
-       Date: 1998.
-       ISBN: 0-471-98141-9
-       Notes: English translation.
-       
-     * Title: "Linux 2.0"
-       Author: Remy Card, Eric Dumas, Franck Mevel.
-       Publisher: Gestión 2000.
-       Date: 1997.
-       Pages: 501.
-       ISBN: 8-480-88208-5
-       Notes: Spanish translation.
-       
+
      * Title: "Unix internals -- the new frontiers"
        Author: Uresh Vahalia.
        Publisher: Prentice Hall.
        Date: 1996.
        Pages: 600.
        ISBN: 0-13-101908-2
-       
-     * Title: "Linux Core Kernel Commentary. Guide to Insider's Knowledge
-       on the Core Kernel of the Linux Code"
-       Author: Scott Maxwell.
-       Publisher: Coriolis.
-       Date: 1999.
-       Pages: 592.
-       ISBN: 1-57610-469-9
-       Notes: CD-ROM included. Line by line commentary of the kernel
-       code.
-       
-     * Title: "Linux IP Stacks Commentary"
-       Author: Stephen Satchell and HBJ Clifford.
-       Publisher: Coriolis.
-       Date: 2000.
-       Pages: ???.
-       ISBN: 1-57610-470-2
-       Notes: Line by line source code commentary book.
-       
+
+     * Title:  "The  Design  and Implementation of the 4.4 BSD UNIX
+       Operating System"
+       Author: Marshall Kirk McKusick, Keith Bostic, Michael J. Karels,
+       John S. Quarterman.
+       Publisher: Addison-Wesley.
+       Date: 1996.
+       ISBN: 0-201-54979-4
+
      * Title: "Programming for the real world - POSIX.4"
        Author: Bill O. Gallmeister.
        Publisher: O'Reilly & Associates, Inc..
@@ -640,18 +611,32 @@
        ISBN: I-56592-074-0
        Notes: Though not being directly about Linux, Linux aims to be
        POSIX. Good reference.
-       
-     * Title: "Understanding the Linux Kernel"
-       Author: Daniel P. Bovet and Marco Cesati.
-       Publisher: O'Reilly & Associates, Inc..
-       Date: 2000.
-       Pages: 702.
-       ISBN: 0-596-00002-2
-       Notes: Further information in
-       http://www.oreilly.com/catalog/linuxkernel/
-       
+
+     * Title:  "UNIX  Systems  for  Modern Architectures: Symmetric
+       Multiprocesssing and Caching for Kernel Programmers"
+       Author: Curt Schimmel.
+       Publisher: Addison Wesley.
+       Date: June, 1994.
+       Pages: 432.
+       ISBN: 0-201-63338-8
+
+     * Title:  "The  Design  and Implementation of the 4.3 BSD UNIX
+       Operating System"
+       Author: Samuel J. Leffler, Marshall Kirk McKusick, Michael J.
+       Karels, John S. Quarterman.
+       Publisher: Addison-Wesley.
+       Date: 1989 (reprinted with corrections on October, 1990).
+       ISBN: 0-201-06196-1
+
+     * Title: "The Design of the UNIX Operating System"
+       Author: Maurice J. Bach.
+       Publisher: Prentice Hall.
+       Date: 1986.
+       Pages: 471.
+       ISBN: 0-13-201757-1
+
      MISCELLANEOUS:
-   
+
      * Name: linux/Documentation
        Author: Many.
        URL: Just look inside your kernel sources.
@@ -660,7 +645,7 @@
        inside the Documentation directory. Some pages from this document
        (including this document itself) have been moved there, and might
        be more up to date than the web version.
-       
+
      * Name: "Linux Source Driver"
        URL: http://lsd.linux.cz
        Keywords: Browsing source code.
@@ -671,7 +656,7 @@
        you can search Linux kernel (fulltext, macros, types, functions
        and variables) and LSD can generate patches for you on the fly
        (files, directories or kernel)".
-       
+
      * Name: "Linux Kernel Source Reference"
        Author: Thomas Graichen.
        URL: http://innominate.org/~graichen/projects/lksr/
@@ -681,27 +666,27 @@
        sources of any version starting from 1.0 up to the (daily updated)
        current version available. Also you can check the differences
        between two versions of a file".
-       
+
      * Name: "Cross-Referencing Linux"
        URL: http://lxr.linux.no/source/
        Keywords: Browsing source code.
        Description: Another web-based Linux kernel source code browser.
        Lots of cross references to variables and functions. You can see
        where they are defined and where they are used.
-       
+
      * Name: "Linux Weekly News"
        URL: http://lwn.net
        Keywords: latest kernel news.
        Description: The title says it all. There's a fixed kernel section
        summarizing developers' work, bug fixes, new features and versions
        produced during the week. Published every Thursday.
-       
+
      * Name: "Kernel Traffic"
-       URL: http://www.kerneltraffic.org/kernel-traffic/
+       URL: http://kt.zork.net/kernel-traffic/
        Keywords: linux-kernel mailing list, weekly kernel news.
        Description: Weekly newsletter covering the most relevant
        discussions of the linux-kernel mailing list.
-       
+
      * Name: "CuTTiNG.eDGe.LiNuX"
        URL: http://edge.kernelnotes.org
        Keywords: changelist.
@@ -709,7 +694,7 @@
        release. What's new, what's better, what's changed. Myrdraal reads
        the patches and describes them. Pointers to the patches are there,
        too.
-       
+
      * Name: "New linux-kernel Mailing List FAQ"
        URL: http://www.tux.org/lkml/
        Keywords: linux-kernel mailing list FAQ.
@@ -719,7 +704,7 @@
        it. Read it to see how to join the mailing list. Dozens of
        interesting questions regarding the list, Linux, developers (who
        is ...?), terms (what is...?) are answered here too. Just read it.
-       
+
      * Name: "Linux Virtual File System"
        Author: Peter J. Braam.
        URL: http://www.coda.cs.cmu.edu/doc/talks/linuxvfs/
@@ -727,10 +712,10 @@
        Description: Set of slides, presumably from a presentation on the
        Linux VFS layer. Covers version 2.1.x, with dentries and the
        dcache.
-       
+
      * Name: "Gary's Encyclopedia - The Linux Kernel"
        Author: Gary (I suppose...).
-       URL: http://members.aa.net/~swear/pedia/kernel.html
+       URL: http://www.lisoleg.net/cgi-bin/lisoleg.pl?view=kernel.htm
        Keywords: links, not found here?.
        Description: Gary's Encyclopedia exists to allow the rapid finding
        of documentation and other information of interest to GNU/Linux
@@ -738,7 +723,7 @@
        categories. This link is for kernel-specific links, documents,
        sites... Look there if you could not find here what you were
        looking for.
-       
+
      * Name: "The home page of Linux-MM"
        Author: The Linux-MM team.
        URL: http://linux-mm.org/
@@ -747,7 +732,7 @@
        Description: Site devoted to Linux Memory Management development.
        Memory related patches, HOWTOs, links, mm developers... Don't miss
        it if you are interested in memory management development!
-       
+
      * Name: "Kernel Newbies IRC Channel"
        URL: http://www.kernelnewbies.org
        Keywords: IRC, newbies, channel, asking doubts.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index abd575c..c479d30 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -48,6 +48,7 @@
 	ISAPNP	ISA PnP code is enabled.
 	ISDN	Appropriate ISDN support is enabled.
 	JOY	Appropriate joystick support is enabled.
+	LIBATA  Libata driver is enabled
 	LP	Printer support is enabled.
 	LOOP	Loopback device support is enabled.
 	M68k	M68k architecture is enabled.
@@ -863,7 +864,14 @@
 			Format: <1-256>
 
 	maxcpus=	[SMP] Maximum number of processors that	an SMP kernel
-			should make use of
+			should make use of.
+			Using "nosmp" or "maxcpus=0" will disable SMP
+			entirely (the MPS table probe still happens, though).
+			A command-line option of "maxcpus=<NUM>", where <NUM>
+			is an integer greater than 0, limits the maximum number
+			of CPUs activated in SMP mode to <NUM>.
+			Using "maxcpus=1" on an SMP kernel is the trivial
+			case of an SMP kernel with only one CPU.
 
 	max_addr=[KMG]	[KNL,BOOT,ia64] All physical memory greater than or
 			equal to this physical address is ignored.
@@ -1038,6 +1046,10 @@
 			emulation library even if a 387 maths coprocessor
 			is present.
 
+	noacpi		[LIBATA] Disables use of ACPI in libata suspend/resume
+			when set.
+			Format: <int>
+
 	noaliencache	[MM, NUMA] Disables the allcoation of alien caches in
 			the slab allocator.  Saves per-node memory, but will
 			impact performance on real NUMA hardware.
@@ -1275,6 +1287,12 @@
 				This sorting is done to get a device
 				order compatible with older (<= 2.4) kernels.
 		nobfsort	Don't sort PCI devices into breadth-first order.
+		cbiosize=nn[KMG]	The fixed amount of bus space which is
+				reserved for the CardBus bridge's IO window.
+				The default value is 256 bytes.
+		cbmemsize=nn[KMG]	The fixed amount of bus space which is
+				reserved for the CardBus bridge's memory
+				window. The default value is 64 megabytes.
 
 	pcmv=		[HW,PCMCIA] BadgePAD 4
 
diff --git a/Documentation/pci.txt b/Documentation/pci.txt
index fd5028e..cdf2f3c 100644
--- a/Documentation/pci.txt
+++ b/Documentation/pci.txt
@@ -205,8 +205,8 @@
 	  exclusively called by the probe() routine, can be marked __devinit.
 	  Ditto for remove() and __devexit.
 
-	o If mydriver_probe() is marked with __devinit(), then all address
-	  references to mydriver_probe must use __devexit_p(mydriver_probe)
+	o If mydriver_remove() is marked with __devexit(), then all address
+	  references to mydriver_remove must use __devexit_p(mydriver_remove)
 	  (in the struct pci_driver declaration for example).
 	  __devexit_p() will generate the function name _or_ NULL if the
 	  function will be discarded.  For an example, see drivers/net/tg3.c.
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index 3b51467..b41397d 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -497,7 +497,7 @@
       |   |- device_type = "cpu"
       |   |- reg = <0>
       |   |- clock-frequency = <5f5e1000>
-      |   |- linux,boot-cpu
+      |   |- 64-bit
       |   |- linux,phandle = <2>
       |
       o memory@0
@@ -509,7 +509,6 @@
       o chosen
         |- name = "chosen"
         |- bootargs = "root=/dev/sda2"
-        |- linux,platform = <00000600>
         |- linux,phandle = <4>
 
 This tree is almost a minimal tree. It pretty much contains the
@@ -519,7 +518,7 @@
 through /chosen, like in this example, the platform type (mandatory)
 and the kernel command line arguments (optional).
 
-The /cpus/PowerPC,970@0/linux,boot-cpu property is an example of a
+The /cpus/PowerPC,970@0/64-bit property is an example of a
 property without a value. All other properties have a value. The
 significance of the #address-cells and #size-cells properties will be
 explained in chapter IV which defines precisely the required nodes and
@@ -733,8 +732,7 @@
       that typically get driven by the same platform code in the
       kernel, you would use a different "model" property but put a
       value in "compatible". The kernel doesn't directly use that
-      value (see /chosen/linux,platform for how the kernel chooses a
-      platform type) but it is generally useful.
+      value but it is generally useful.
 
   The root node is also generally where you add additional properties
   specific to your board like the serial number if any, that sort of
@@ -778,7 +776,6 @@
       bytes
     - d-cache-size : one cell, size of L1 data cache in bytes
     - i-cache-size : one cell, size of L1 instruction cache in bytes
-    - linux, boot-cpu : Should be defined if this cpu is the boot cpu.
 
   Recommended properties:
 
@@ -843,11 +840,6 @@
   the prom_init() trampoline when booting with an OF client interface,
   but that you have to provide yourself when using the flattened format.
 
-  Required properties:
-
-    - linux,platform : This is your platform number as assigned by the
-      architecture maintainers
-
   Recommended properties:
 
     - bootargs : This zero-terminated string is passed as the kernel
diff --git a/Documentation/sh/new-machine.txt b/Documentation/sh/new-machine.txt
index 73988e0..5482bf5 100644
--- a/Documentation/sh/new-machine.txt
+++ b/Documentation/sh/new-machine.txt
@@ -17,7 +17,7 @@
 in arch/sh/kernel/ directly, with board-specific headers ending up in
 include/asm-sh/. For the new kernel, things are broken out by board type,
 companion chip type, and CPU type. Looking at a tree view of this directory
-heirarchy looks like the following:
+hierarchy looks like the following:
 
 Board-specific code:
 
@@ -108,7 +108,7 @@
 member itself.
 
 There are a few things that each board is required to have, both in the
-arch/sh/boards and the include/asm-sh/ heirarchy. In order to better
+arch/sh/boards and the include/asm-sh/ hierarchy. In order to better
 explain this, we use some examples for adding an imaginary board. For
 setup code, we're required at the very least to provide definitions for
 get_system_type() and platform_setup(). For our imaginary board, this
diff --git a/Documentation/sony-laptop.txt b/Documentation/sony-laptop.txt
new file mode 100644
index 0000000..dfd26df
--- /dev/null
+++ b/Documentation/sony-laptop.txt
@@ -0,0 +1,106 @@
+Sony Notebook Control Driver (SNC) Readme
+-----------------------------------------
+	Copyright (C) 2004- 2005 Stelian Pop <stelian@popies.net>
+	Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
+
+This mini-driver drives the SNC device present in the ACPI BIOS of
+the Sony Vaio laptops.
+
+It gives access to some extra laptop functionalities. In its current
+form, this driver let the user set or query the screen brightness
+through the backlight subsystem and remove/apply power to some devices.
+
+Backlight control:
+------------------
+If your laptop model supports it, you will find sysfs files in the
+/sys/class/backlight/sony/
+directory. You will be able to query and set the current screen
+brightness:
+	brightness		get/set screen brightness (an iteger
+				between 0 and 7)
+	actual_brightness	reading from this file will query the HW
+				to get real brightness value
+	max_brightness		the maximum brightness value
+
+
+Platform specific:
+------------------
+Loading the sony-laptop module will create a
+/sys/devices/platform/sony-laptop/
+directory populated with some files.
+
+You then read/write integer values from/to those files by using
+standard UNIX tools.
+
+The files are:
+	brightness_default	screen brightness which will be set
+				when the laptop will be rebooted
+	cdpower			power on/off the internal CD drive
+	audiopower		power on/off the internal sound card
+	lanpower		power on/off the internal ethernet card
+				(only in debug mode)
+
+Note that some files may be missing if they are not supported
+by your particular laptop model.
+
+Example usage:
+	# echo "1" > /sys/devices/platform/sony-laptop/brightness_default
+sets the lowest screen brightness for the next and later reboots,
+	# echo "8" > /sys/devices/platform/sony-laptop/brightness_default
+sets the highest screen brightness for the next and later reboots,
+	# cat /sys/devices/platform/sony-laptop/brightness_default
+retrieves the value.
+
+	# echo "0" > /sys/devices/platform/sony-laptop/audiopower
+powers off the sound card,
+	# echo "1" > /sys/devices/platform/sony-laptop/audiopower
+powers on the sound card.
+
+Development:
+------------
+
+If you want to help with the development of this driver (and
+you are not afraid of any side effects doing strange things with
+your ACPI BIOS could have on your laptop), load the driver and
+pass the option 'debug=1'.
+
+REPEAT: DON'T DO THIS IF YOU DON'T LIKE RISKY BUSINESS.
+
+In your kernel logs you will find the list of all ACPI methods
+the SNC device has on your laptop. You can see the GCDP/GCDP methods
+used to pwer on/off the CD drive, but there are others.
+
+I HAVE NO IDEA WHAT THOSE METHODS DO.
+
+The sony-laptop driver creates, for some of those methods (the most
+current ones found on several Vaio models), an entry under
+/sys/devices/platform/sony-laptop, just like the 'cdpower' one.
+You can create other entries corresponding to your own laptop methods by
+further editing the source (see the 'sony_acpi_values' table, and add a new
+entry to this table with your get/set method names using the
+HANDLE_NAMES macro).
+
+Your mission, should you accept it, is to try finding out what
+those entries are for, by reading/writing random values from/to those
+files and find out what is the impact on your laptop.
+
+Should you find anything interesting, please report it back to me,
+I will not disavow all knowledge of your actions :)
+
+Bugs/Limitations:
+-----------------
+
+* This driver is not based on official documentation from Sony
+  (because there is none), so there is no guarantee this driver
+  will work at all, or do the right thing. Although this hasn't
+  happened to me, this driver could do very bad things to your
+  laptop, including permanent damage.
+
+* The sony-laptop and sonypi drivers do not interact at all. In the
+  future, sonypi could use sony-laptop to do (part of) its business.
+
+* spicctrl, which is the userspace tool used to communicate with the
+  sonypi driver (through /dev/sonypi) does not try to use the
+  sony-laptop driver. In the future, spicctrl could try sonypi first,
+  and if it isn't present, try sony-laptop instead.
+
diff --git a/Documentation/video4linux/bttv/Insmod-options b/Documentation/video4linux/bttv/Insmod-options
index bb7c2ca..5ef7578 100644
--- a/Documentation/video4linux/bttv/Insmod-options
+++ b/Documentation/video4linux/bttv/Insmod-options
@@ -57,7 +57,7 @@
 		i2c_udelay=     Allow reduce I2C speed. Default is 5 usecs
 				(meaning 66,67 Kbps). The default is the
 				maximum supported speed by kernel bitbang
-				algoritm. You may use lower numbers, if I2C
+				algorithm. You may use lower numbers, if I2C
 				messages are lost (16 is known to work on
 				all supported cards).
 
diff --git a/MAINTAINERS b/MAINTAINERS
index c0f9a1a..6261597 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -247,6 +247,13 @@
 W:	http://acpi.sourceforge.net/
 S:	Supported
 
+ACPI VIDEO DRIVER
+P:	Luming Yu
+M:	luming.yu@intel.com
+L:	linux-acpi@vger.kernel.org
+W:	http://acpi.sourceforge.net/
+S:	Supported
+
 AD1816 SOUND DRIVER
 P:	Thorsten Knabe
 M:	Thorsten Knabe <linux@thorsten-knabe.de>
@@ -268,6 +275,12 @@
 L:	lm-sensors@lm-sensors.org
 S:	Maintained
 
+ADM1029 HARDWARE MONITOR DRIVER
+P:	Corentin Labbe
+M:	corentin.labbe@geomatys.fr
+L:	lm-sensors@lm-sensors.org
+S:	Maintained
+
 ADT746X FAN DRIVER
 P:	Colin Leroy
 M:	colin@colino.net
@@ -3061,6 +3074,8 @@
 SONY VAIO CONTROL DEVICE DRIVER
 P:	Stelian Pop
 M:	stelian@popies.net
+P:	Mattia Dongili
+M:	malattia@linux.it
 W:	http://popies.net/sonypi/
 S:	Maintained
 
diff --git a/README b/README
index 46a66c6..159912c 100644
--- a/README
+++ b/README
@@ -24,7 +24,7 @@
   today Linux also runs on (at least) the Compaq Alpha AXP, Sun SPARC and
   UltraSPARC, Motorola 68000, PowerPC, PowerPC64, ARM, Hitachi SuperH, Cell,
   IBM S/390, MIPS, HP PA-RISC, Intel IA-64, DEC VAX, AMD x86-64, AXIS CRIS,
-  Cris, Xtensa, AVR32 and Renesas M32R architectures.
+  Xtensa, AVR32 and Renesas M32R architectures.
 
   Linux is easily portable to most general-purpose 32- or 64-bit architectures
   as long as they have a paged memory management unit (PMMU) and a port of the
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5c79519..4409561 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -245,6 +245,8 @@
 
 config ARCH_IOP13XX
 	bool "IOP13xx-based"
+	depends on MMU
+	select PLAT_IOP
 	select PCI
 	help
 	  Support for Intel's IOP13XX (XScale) family of processors.
@@ -283,6 +285,14 @@
 	  If you have any questions or comments about the Linux kernel port
 	  to this board, send e-mail to <sjhill@cotw.com>.
 
+config ARCH_NS9XXX
+	bool "NetSilicon NS9xxx"
+	help
+	  Say Y here if you intend to run this kernel on a NetSilicon NS9xxx
+	  System.
+
+	  <http://www.digi.com/products/microprocessors/index.jsp>
+
 config ARCH_PNX4008
 	bool "Philips Nexperia PNX4008 Mobile"
 	help
@@ -292,6 +302,7 @@
 	bool "PXA2xx-based"
 	depends on MMU
 	select ARCH_MTD_XIP
+	select GENERIC_TIME
 	help
 	  Support for Intel's PXA2XX processor line.
 
@@ -316,7 +327,7 @@
 	  Support for StrongARM 11x0 based boards.
 
 config ARCH_S3C2410
-	bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442"
+	bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
 	help
 	  Samsung S3C2410X CPU based systems, such as the Simtec Electronics
 	  BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
@@ -376,7 +387,16 @@
 
 source "arch/arm/mach-omap2/Kconfig"
 
+source "arch/arm/plat-s3c24xx/Kconfig"
+
+if ARCH_S3C2410
+source "arch/arm/mach-s3c2400/Kconfig"
 source "arch/arm/mach-s3c2410/Kconfig"
+source "arch/arm/mach-s3c2412/Kconfig"
+source "arch/arm/mach-s3c2440/Kconfig"
+source "arch/arm/mach-s3c2442/Kconfig"
+source "arch/arm/mach-s3c2443/Kconfig"
+endif
 
 source "arch/arm/mach-lh7a40x/Kconfig"
 
@@ -390,10 +410,12 @@
 
 source "arch/arm/mach-realview/Kconfig"
 
-source "arch/arm/mach-at91rm9200/Kconfig"
+source "arch/arm/mach-at91/Kconfig"
 
 source "arch/arm/mach-netx/Kconfig"
 
+source "arch/arm/mach-ns9xxx/Kconfig"
+
 # Definitions to make life easier
 config ARCH_ACORN
 	bool
@@ -405,7 +427,7 @@
 
 config IWMMXT
 	bool "Enable iWMMXt support"
-	depends CPU_XSCALE || CPU_XSC3
+	depends on CPU_XSCALE || CPU_XSC3
 	default y if PXA27x
 	help
 	  Enable support for iWMMXt context switching at run time if
@@ -751,6 +773,20 @@
 	  be linked for and stored to.  This address is dependent on your
 	  own flash usage.
 
+config KEXEC
+	bool "Kexec system call (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	help
+	  kexec is a system call that implements the ability to shutdown your
+	  current kernel, and to start another kernel.  It is like a reboot
+	  but it is indepedent of the system firmware.   And like a reboot
+	  you can start any kernel with it, not just Linux.
+
+	  It is an ongoing process to be certain the hardware in a machine
+	  is properly shutdown, so do not be surprised if this code does not
+	  initially work for you.  It may help to enable device hotplugging
+	  support.
+
 endmenu
 
 if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX )
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 000f110..1320418 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -124,10 +124,12 @@
  machine-$(CONFIG_ARCH_H720X)	   := h720x
  machine-$(CONFIG_ARCH_AAEC2000)   := aaec2000
  machine-$(CONFIG_ARCH_REALVIEW)   := realview
- machine-$(CONFIG_ARCH_AT91)       := at91rm9200
- machine-$(CONFIG_ARCH_EP93XX)     := ep93xx
- machine-$(CONFIG_ARCH_PNX4008)    := pnx4008
- machine-$(CONFIG_ARCH_NETX)       := netx
+ machine-$(CONFIG_ARCH_AT91)	   := at91rm9200
+ machine-$(CONFIG_ARCH_EP93XX)	   := ep93xx
+ machine-$(CONFIG_ARCH_PNX4008)	   := pnx4008
+ machine-$(CONFIG_ARCH_NETX)	   := netx
+ machine-$(CONFIG_ARCH_NS9XXX)	   := ns9xxx
+ textofs-$(CONFIG_ARCH_NS9XXX)	   := 0x00108000
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
@@ -149,7 +151,7 @@
 else
 MACHINE  :=
 endif
-  
+
 export	TEXT_OFFSET GZFLAGS MMUEXT
 
 # Do we have FASTFPE?
@@ -161,6 +163,11 @@
 # If we have a machine-specific directory, then include it in the build.
 core-y				+= arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
 core-y				+= $(MACHINE)
+core-$(CONFIG_ARCH_S3C2410)	+= arch/arm/mach-s3c2400/
+core-$(CONFIG_ARCH_S3C2410)	+= arch/arm/mach-s3c2412/
+core-$(CONFIG_ARCH_S3C2410)	+= arch/arm/mach-s3c2440/
+core-$(CONFIG_ARCH_S3C2410)	+= arch/arm/mach-s3c2442/
+core-$(CONFIG_ARCH_S3C2410)	+= arch/arm/mach-s3c2443/
 core-$(CONFIG_FPE_NWFPE)	+= arch/arm/nwfpe/
 core-$(CONFIG_FPE_FASTFPE)	+= $(FASTFPE_OBJ)
 core-$(CONFIG_VFP)		+= arch/arm/vfp/
@@ -168,6 +175,7 @@
 # If we have a common platform directory, then include it in the build.
 core-$(CONFIG_PLAT_IOP)		+= arch/arm/plat-iop/
 core-$(CONFIG_ARCH_OMAP)	+= arch/arm/plat-omap/
+core-$(CONFIG_PLAT_S3C24XX)		+= arch/arm/plat-s3c24xx/
 
 drivers-$(CONFIG_OPROFILE)      += arch/arm/oprofile/
 drivers-$(CONFIG_ARCH_CLPS7500)	+= drivers/acorn/char/
diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore
new file mode 100644
index 0000000..171a085
--- /dev/null
+++ b/arch/arm/boot/.gitignore
@@ -0,0 +1,2 @@
+Image
+zImage
diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore
new file mode 100644
index 0000000..aefee20
--- /dev/null
+++ b/arch/arm/boot/compressed/.gitignore
@@ -0,0 +1 @@
+piggy.gz
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 2e635b8..6fbe772 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -32,7 +32,6 @@
 
 #include <asm/cacheflush.h>
 
-#undef DEBUG
 #undef STATS
 
 #ifdef STATS
@@ -66,14 +65,13 @@
 };
 
 struct dmabounce_device_info {
-	struct list_head node;
-
 	struct device *dev;
 	struct list_head safe_buffers;
 #ifdef STATS
 	unsigned long total_allocs;
 	unsigned long map_op_count;
 	unsigned long bounce_count;
+	int attr_res;
 #endif
 	struct dmabounce_pool	small;
 	struct dmabounce_pool	large;
@@ -81,34 +79,24 @@
 	rwlock_t lock;
 };
 
-static LIST_HEAD(dmabounce_devs);
-
 #ifdef STATS
-static void print_alloc_stats(struct dmabounce_device_info *device_info)
+static ssize_t dmabounce_show(struct device *dev, struct device_attribute *attr,
+			      char *buf)
 {
-	printk(KERN_INFO
-		"%s: dmabounce: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n",
-		device_info->dev->bus_id,
-		device_info->small.allocs, device_info->large.allocs,
+	struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
+	return sprintf(buf, "%lu %lu %lu %lu %lu %lu\n",
+		device_info->small.allocs,
+		device_info->large.allocs,
 		device_info->total_allocs - device_info->small.allocs -
 			device_info->large.allocs,
-		device_info->total_allocs);
+		device_info->total_allocs,
+		device_info->map_op_count,
+		device_info->bounce_count);
 }
+
+static DEVICE_ATTR(dmabounce_stats, 0400, dmabounce_show, NULL);
 #endif
 
-/* find the given device in the dmabounce device list */
-static inline struct dmabounce_device_info *
-find_dmabounce_dev(struct device *dev)
-{
-	struct dmabounce_device_info *d;
-
-	list_for_each_entry(d, &dmabounce_devs, node)
-		if (d->dev == dev)
-			return d;
-
-	return NULL;
-}
-
 
 /* allocate a 'safe' buffer and keep track of it */
 static inline struct safe_buffer *
@@ -162,8 +150,6 @@
 	if (pool)
 		pool->allocs++;
 	device_info->total_allocs++;
-	if (device_info->total_allocs % 1000 == 0)
-		print_alloc_stats(device_info);
 #endif
 
 	write_lock_irqsave(&device_info->lock, flags);
@@ -218,20 +204,11 @@
 
 /* ************************************************** */
 
-#ifdef STATS
-static void print_map_stats(struct dmabounce_device_info *device_info)
-{
-	dev_info(device_info->dev,
-		"dmabounce: map_op_count=%lu, bounce_count=%lu\n",
-		device_info->map_op_count, device_info->bounce_count);
-}
-#endif
-
 static inline dma_addr_t
 map_single(struct device *dev, void *ptr, size_t size,
 		enum dma_data_direction dir)
 {
-	struct dmabounce_device_info *device_info = find_dmabounce_dev(dev);
+	struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
 	dma_addr_t dma_addr;
 	int needs_bounce = 0;
 
@@ -281,10 +258,14 @@
 		ptr = buf->safe;
 
 		dma_addr = buf->safe_dma_addr;
+	} else {
+		/*
+		 * We don't need to sync the DMA buffer since
+		 * it was allocated via the coherent allocators.
+		 */
+		consistent_sync(ptr, size, dir);
 	}
 
-	consistent_sync(ptr, size, dir);
-
 	return dma_addr;
 }
 
@@ -292,7 +273,7 @@
 unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 		enum dma_data_direction dir)
 {
-	struct dmabounce_device_info *device_info = find_dmabounce_dev(dev);
+	struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
 	struct safe_buffer *buf = NULL;
 
 	/*
@@ -317,12 +298,12 @@
 		DO_STATS ( device_info->bounce_count++ );
 
 		if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
-			unsigned long ptr;
+			void *ptr = buf->ptr;
 
 			dev_dbg(dev,
 				"%s: copy back safe %p to unsafe %p size %d\n",
-				__func__, buf->safe, buf->ptr, size);
-			memcpy(buf->ptr, buf->safe, size);
+				__func__, buf->safe, ptr, size);
+			memcpy(ptr, buf->safe, size);
 
 			/*
 			 * DMA buffers must have the same cache properties
@@ -332,8 +313,8 @@
 			 * bidirectional case because we know the cache
 			 * lines will be coherent with the data written.
 			 */
-			ptr = (unsigned long)buf->ptr;
 			dmac_clean_range(ptr, ptr + size);
+			outer_clean_range(__pa(ptr), __pa(ptr) + size);
 		}
 		free_safe_buffer(device_info, buf);
 	}
@@ -343,7 +324,7 @@
 sync_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 		enum dma_data_direction dir)
 {
-	struct dmabounce_device_info *device_info = find_dmabounce_dev(dev);
+	struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
 	struct safe_buffer *buf = NULL;
 
 	if (device_info)
@@ -397,7 +378,10 @@
 		default:
 			BUG();
 		}
-		consistent_sync(buf->safe, size, dir);
+		/*
+		 * No need to sync the safe buffer - it was allocated
+		 * via the coherent allocators.
+		 */
 	} else {
 		consistent_sync(dma_to_virt(dev, dma_addr), size, dir);
 	}
@@ -604,9 +588,10 @@
 	device_info->total_allocs = 0;
 	device_info->map_op_count = 0;
 	device_info->bounce_count = 0;
+	device_info->attr_res = device_create_file(dev, &dev_attr_dmabounce_stats);
 #endif
 
-	list_add(&device_info->node, &dmabounce_devs);
+	dev->archdata.dmabounce = device_info;
 
 	printk(KERN_INFO "dmabounce: registered device %s on %s bus\n",
 		dev->bus_id, dev->bus->name);
@@ -623,7 +608,9 @@
 void
 dmabounce_unregister_dev(struct device *dev)
 {
-	struct dmabounce_device_info *device_info = find_dmabounce_dev(dev);
+	struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
+
+	dev->archdata.dmabounce = NULL;
 
 	if (!device_info) {
 		printk(KERN_WARNING
@@ -645,12 +632,10 @@
 		dma_pool_destroy(device_info->large.pool);
 
 #ifdef STATS
-	print_alloc_stats(device_info);
-	print_map_stats(device_info);
+	if (device_info->attr_res == 0)
+		device_remove_file(dev, &dev_attr_dmabounce_stats);
 #endif
 
-	list_del(&device_info->node);
-
 	kfree(device_info);
 
 	printk(KERN_INFO "dmabounce: device %s on %s bus unregistered\n",
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 09b9d1b..4deece5 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -14,7 +14,9 @@
  *
  * o There is one CPU Interface per CPU, which sends interrupts sent
  *   by the Distributor, and interrupts generated locally, to the
- *   associated CPU.
+ *   associated CPU. The base address of the CPU interface is usually
+ *   aliased so that the same address points to different chips depending
+ *   on the CPU it is accessed from.
  *
  * Note that IRQs 0-31 are special - they are local to each CPU.
  * As such, the enable set/clear, pending set/clear and active bit
@@ -31,10 +33,38 @@
 #include <asm/mach/irq.h>
 #include <asm/hardware/gic.h>
 
-static void __iomem *gic_dist_base;
-static void __iomem *gic_cpu_base;
 static DEFINE_SPINLOCK(irq_controller_lock);
 
+struct gic_chip_data {
+	unsigned int irq_offset;
+	void __iomem *dist_base;
+	void __iomem *cpu_base;
+};
+
+#ifndef MAX_GIC_NR
+#define MAX_GIC_NR	1
+#endif
+
+static struct gic_chip_data gic_data[MAX_GIC_NR];
+
+static inline void __iomem *gic_dist_base(unsigned int irq)
+{
+	struct gic_chip_data *gic_data = get_irq_chip_data(irq);
+	return gic_data->dist_base;
+}
+
+static inline void __iomem *gic_cpu_base(unsigned int irq)
+{
+	struct gic_chip_data *gic_data = get_irq_chip_data(irq);
+	return gic_data->cpu_base;
+}
+
+static inline unsigned int gic_irq(unsigned int irq)
+{
+	struct gic_chip_data *gic_data = get_irq_chip_data(irq);
+	return irq - gic_data->irq_offset;
+}
+
 /*
  * Routines to acknowledge, disable and enable interrupts
  *
@@ -55,8 +85,8 @@
 	u32 mask = 1 << (irq % 32);
 
 	spin_lock(&irq_controller_lock);
-	writel(mask, gic_dist_base + GIC_DIST_ENABLE_CLEAR + (irq / 32) * 4);
-	writel(irq, gic_cpu_base + GIC_CPU_EOI);
+	writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4);
+	writel(gic_irq(irq), gic_cpu_base(irq) + GIC_CPU_EOI);
 	spin_unlock(&irq_controller_lock);
 }
 
@@ -65,7 +95,7 @@
 	u32 mask = 1 << (irq % 32);
 
 	spin_lock(&irq_controller_lock);
-	writel(mask, gic_dist_base + GIC_DIST_ENABLE_CLEAR + (irq / 32) * 4);
+	writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4);
 	spin_unlock(&irq_controller_lock);
 }
 
@@ -74,14 +104,14 @@
 	u32 mask = 1 << (irq % 32);
 
 	spin_lock(&irq_controller_lock);
-	writel(mask, gic_dist_base + GIC_DIST_ENABLE_SET + (irq / 32) * 4);
+	writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_SET + (gic_irq(irq) / 32) * 4);
 	spin_unlock(&irq_controller_lock);
 }
 
 #ifdef CONFIG_SMP
 static void gic_set_cpu(unsigned int irq, cpumask_t mask_val)
 {
-	void __iomem *reg = gic_dist_base + GIC_DIST_TARGET + (irq & ~3);
+	void __iomem *reg = gic_dist_base(irq) + GIC_DIST_TARGET + (gic_irq(irq) & ~3);
 	unsigned int shift = (irq % 4) * 8;
 	unsigned int cpu = first_cpu(mask_val);
 	u32 val;
@@ -95,6 +125,37 @@
 }
 #endif
 
+static void fastcall gic_handle_cascade_irq(unsigned int irq,
+					    struct irq_desc *desc)
+{
+	struct gic_chip_data *chip_data = get_irq_data(irq);
+	struct irq_chip *chip = get_irq_chip(irq);
+	unsigned int cascade_irq;
+	unsigned long status;
+
+	/* primary controller ack'ing */
+	chip->ack(irq);
+
+	spin_lock(&irq_controller_lock);
+	status = readl(chip_data->cpu_base + GIC_CPU_INTACK);
+	spin_unlock(&irq_controller_lock);
+
+	cascade_irq = (status & 0x3ff);
+	if (cascade_irq > 1020)
+		goto out;
+	if (cascade_irq < 32 || cascade_irq >= NR_IRQS) {
+		do_bad_IRQ(cascade_irq, desc);
+		goto out;
+	}
+
+	cascade_irq += chip_data->irq_offset;
+	generic_handle_irq(cascade_irq);
+
+ out:
+	/* primary controller unmasking */
+	chip->unmask(irq);
+}
+
 static struct irq_chip gic_chip = {
 	.name		= "GIC",
 	.ack		= gic_ack_irq,
@@ -105,15 +166,29 @@
 #endif
 };
 
-void __init gic_dist_init(void __iomem *base)
+void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
+{
+	if (gic_nr >= MAX_GIC_NR)
+		BUG();
+	if (set_irq_data(irq, &gic_data[gic_nr]) != 0)
+		BUG();
+	set_irq_chained_handler(irq, gic_handle_cascade_irq);
+}
+
+void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
+			  unsigned int irq_start)
 {
 	unsigned int max_irq, i;
 	u32 cpumask = 1 << smp_processor_id();
 
+	if (gic_nr >= MAX_GIC_NR)
+		BUG();
+
 	cpumask |= cpumask << 8;
 	cpumask |= cpumask << 16;
 
-	gic_dist_base = base;
+	gic_data[gic_nr].dist_base = base;
+	gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31;
 
 	writel(0, base + GIC_DIST_CTRL);
 
@@ -158,8 +233,9 @@
 	/*
 	 * Setup the Linux IRQ subsystem.
 	 */
-	for (i = 29; i < max_irq; i++) {
+	for (i = irq_start; i < gic_data[gic_nr].irq_offset + max_irq; i++) {
 		set_irq_chip(i, &gic_chip);
+		set_irq_chip_data(i, &gic_data[gic_nr]);
 		set_irq_handler(i, handle_level_irq);
 		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
 	}
@@ -167,9 +243,13 @@
 	writel(1, base + GIC_DIST_CTRL);
 }
 
-void __cpuinit gic_cpu_init(void __iomem *base)
+void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base)
 {
-	gic_cpu_base = base;
+	if (gic_nr >= MAX_GIC_NR)
+		BUG();
+
+	gic_data[gic_nr].cpu_base = base;
+
 	writel(0xf0, base + GIC_CPU_PRIMASK);
 	writel(1, base + GIC_CPU_CTRL);
 }
@@ -179,6 +259,7 @@
 {
 	unsigned long map = *cpus_addr(cpumask);
 
-	writel(map << 16 | irq, gic_dist_base + GIC_DIST_SOFTINT);
+	/* this always happens on GIC0 */
+	writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
 }
 #endif
diff --git a/arch/arm/configs/at91sam9263ek_defconfig b/arch/arm/configs/at91sam9263ek_defconfig
new file mode 100644
index 0000000..c72ab82
--- /dev/null
+++ b/arch/arm/configs/at91sam9263ek_defconfig
@@ -0,0 +1,1184 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.20-rc1
+# Mon Jan  8 16:06:54 2007
+#
+CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+CONFIG_ARCH_AT91SAM9263=y
+
+#
+# AT91SAM9263 Board Type
+#
+CONFIG_MACH_AT91SAM9263EK=y
+
+#
+# AT91 Board Options
+#
+CONFIG_MTD_AT91_DATAFLASH_CARD=y
+# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set
+
+#
+# AT91 Feature Selections
+#
+# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+
+#
+# Bus support
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+# CONFIG_APM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_AT91=y
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_TSDEV=y
+CONFIG_INPUT_TSDEV_SCREEN_X=240
+CONFIG_INPUT_TSDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_AT91=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+# CONFIG_TIFM_CORE is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MULTITHREAD_PROBE is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# 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_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_TOUCHSCREEN is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_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_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=y
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+CONFIG_USB_ZERO=m
+# CONFIG_USB_ETH is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_AT91=m
+# CONFIG_MMC_TIFM_SD is not set
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/arm/configs/ateb9200_defconfig b/arch/arm/configs/ateb9200_defconfig
index 3de5c64..baa9769 100644
--- a/arch/arm/configs/ateb9200_defconfig
+++ b/arch/arm/configs/ateb9200_defconfig
@@ -1066,7 +1066,7 @@
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_RS5C372 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
-CONFIG_RTC_DRV_AT91=y
+CONFIG_RTC_DRV_AT91RM9200=y
 # CONFIG_RTC_DRV_TEST is not set
 
 #
diff --git a/arch/arm/configs/csb337_defconfig b/arch/arm/configs/csb337_defconfig
index 2cadd51..88e5d28 100644
--- a/arch/arm/configs/csb337_defconfig
+++ b/arch/arm/configs/csb337_defconfig
@@ -355,10 +355,12 @@
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0
+CONFIG_MTD_PHYSMAP_LEN=0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=0
 # CONFIG_MTD_ARM_INTEGRATOR is not set
 # CONFIG_MTD_PLATRAM is not set
-CONFIG_MTD_CSB337=y
 
 #
 # Self-contained MTD device drivers
@@ -986,7 +988,7 @@
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_RS5C372 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
-CONFIG_RTC_DRV_AT91=y
+CONFIG_RTC_DRV_AT91RM9200=y
 # CONFIG_RTC_DRV_TEST is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
diff --git a/arch/arm/configs/csb637_defconfig b/arch/arm/configs/csb637_defconfig
index 94908c1..669f035 100644
--- a/arch/arm/configs/csb637_defconfig
+++ b/arch/arm/configs/csb637_defconfig
@@ -355,10 +355,12 @@
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0
+CONFIG_MTD_PHYSMAP_LEN=0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=0
 # CONFIG_MTD_ARM_INTEGRATOR is not set
 # CONFIG_MTD_PLATRAM is not set
-CONFIG_MTD_CSB637=y
 
 #
 # Self-contained MTD device drivers
diff --git a/arch/arm/configs/kafa_defconfig b/arch/arm/configs/kafa_defconfig
index a4cdafc..a0f48d5 100644
--- a/arch/arm/configs/kafa_defconfig
+++ b/arch/arm/configs/kafa_defconfig
@@ -718,7 +718,7 @@
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_RS5C372 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
-CONFIG_RTC_DRV_AT91=y
+CONFIG_RTC_DRV_AT91RM9200=y
 # CONFIG_RTC_DRV_TEST is not set
 
 #
diff --git a/arch/arm/configs/ns9xxx_defconfig b/arch/arm/configs/ns9xxx_defconfig
new file mode 100644
index 0000000..0e5794c
--- /dev/null
+++ b/arch/arm/configs/ns9xxx_defconfig
@@ -0,0 +1,621 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.20
+# Thu Feb 15 20:51:47 2007
+#
+CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_UTS_NS is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_L7200 is not set
+CONFIG_ARCH_NS9XXX=y
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# NS9xxx Implementations
+#
+CONFIG_MACH_CC9P9360DEV=y
+CONFIG_PROCESSOR_NS9360=y
+CONFIG_BOARD_A9M9750DEV=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+
+#
+# Bus support
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+# CONFIG_APM is not set
+
+#
+# Networking
+#
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# ISDN subsystem
+#
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+# CONFIG_TIFM_CORE is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_ICEDCC=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index 3b31a33..df19e36 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc4
-# Fri Nov  3 17:41:31 2006
+# Linux kernel version: 2.6.20
+# Thu Feb 15 11:26:24 2007
 #
 CONFIG_ARM=y
 # CONFIG_GENERIC_TIME is not set
@@ -11,6 +11,8 @@
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_VECTORS_BASE=0xffff0000
@@ -37,13 +39,14 @@
 # CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
-# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -76,7 +79,9 @@
 # Block layer
 #
 CONFIG_BLOCK=y
+# CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -110,6 +115,7 @@
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP23XX is not set
@@ -122,54 +128,73 @@
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_OMAP is not set
+CONFIG_PLAT_S3C24XX=y
+CONFIG_CPU_S3C244X=y
+CONFIG_PM_SIMTEC=y
+# CONFIG_S3C2410_BOOT_WATCHDOG is not set
+# CONFIG_S3C2410_BOOT_ERROR_RESET is not set
+# CONFIG_S3C2410_PM_DEBUG is not set
+# CONFIG_S3C2410_PM_CHECK is not set
+CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
+CONFIG_S3C2410_DMA=y
+# CONFIG_S3C2410_DMA_DEBUG is not set
+CONFIG_MACH_SMDK=y
 
 #
-# S3C24XX Implementations
+# S3C2400 Machines
 #
-# CONFIG_MACH_AML_M5900 is not set
+CONFIG_CPU_S3C2410=y
+CONFIG_CPU_S3C2410_DMA=y
+CONFIG_S3C2410_PM=y
+CONFIG_S3C2410_GPIO=y
+CONFIG_S3C2410_CLOCK=y
+
+#
+# S3C2410 Machines
+#
+CONFIG_ARCH_SMDK2410=y
+CONFIG_ARCH_H1940=y
+CONFIG_PM_H1940=y
+CONFIG_MACH_N30=y
+CONFIG_ARCH_BAST=y
+CONFIG_MACH_OTOM=y
+CONFIG_MACH_AML_M5900=y
+CONFIG_BAST_PC104_IRQ=y
+CONFIG_MACH_VR1000=y
+CONFIG_CPU_S3C2412=y
+CONFIG_S3C2412_DMA=y
+CONFIG_S3C2412_PM=y
+
+#
+# S3C2412 Machines
+#
+CONFIG_MACH_SMDK2413=y
+CONFIG_MACH_S3C2413=y
+CONFIG_MACH_VSTMS=y
+CONFIG_CPU_S3C2440=y
+CONFIG_S3C2440_DMA=y
+
+#
+# S3C2440 Machines
+#
 CONFIG_MACH_ANUBIS=y
 CONFIG_MACH_OSIRIS=y
-CONFIG_ARCH_BAST=y
-CONFIG_BAST_PC104_IRQ=y
-CONFIG_ARCH_H1940=y
-CONFIG_MACH_N30=y
-CONFIG_MACH_SMDK=y
-CONFIG_ARCH_SMDK2410=y
-CONFIG_ARCH_S3C2440=y
-CONFIG_SMDK2440_CPU2440=y
-CONFIG_SMDK2440_CPU2442=y
-CONFIG_MACH_S3C2413=y
-CONFIG_MACH_SMDK2413=y
-CONFIG_MACH_VR1000=y
 CONFIG_MACH_RX3715=y
-CONFIG_MACH_OTOM=y
+CONFIG_ARCH_S3C2440=y
 CONFIG_MACH_NEXCODER_2440=y
-CONFIG_MACH_VSTMS=y
-CONFIG_S3C2410_CLOCK=y
-CONFIG_S3C2410_PM=y
-CONFIG_CPU_S3C2410_DMA=y
-CONFIG_CPU_S3C2410=y
-CONFIG_S3C2412_PM=y
-CONFIG_CPU_S3C2412=y
-CONFIG_CPU_S3C244X=y
-CONFIG_CPU_S3C2440=y
+CONFIG_SMDK2440_CPU2440=y
 CONFIG_CPU_S3C2442=y
 
 #
-# S3C2410 Boot
+# S3C2442 Machines
 #
-# CONFIG_S3C2410_BOOT_WATCHDOG is not set
-# CONFIG_S3C2410_BOOT_ERROR_RESET is not set
+CONFIG_SMDK2440_CPU2442=y
+CONFIG_CPU_S3C2443=y
 
 #
-# S3C2410 Setup
+# S3C2443 Machines
 #
-CONFIG_S3C2410_DMA=y
-# CONFIG_S3C2410_DMA_DEBUG is not set
-# CONFIG_S3C2410_PM_DEBUG is not set
-# CONFIG_S3C2410_PM_CHECK is not set
-CONFIG_PM_SIMTEC=y
-CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
+CONFIG_MACH_SMDK2443=y
 
 #
 # Processor Type
@@ -196,6 +221,7 @@
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_WRITETHROUGH is not set
 # CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
 
 #
 # Bus support
@@ -303,6 +329,7 @@
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -385,6 +412,7 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
@@ -531,6 +559,11 @@
 # CONFIG_SCSI_NETLINK is not set
 
 #
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
@@ -682,7 +715,7 @@
 # CONFIG_DIGIEPCA is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
-# CONFIG_ISI is not set
+# CONFIG_MOXA_SMARTIO_NEW is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
@@ -700,13 +733,14 @@
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
 # CONFIG_SERIAL_8250_FOURPORT is not set
 # CONFIG_SERIAL_8250_ACCENT is not set
 # CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
 # CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
 
 #
 # Non-8250 serial port support
@@ -755,10 +789,6 @@
 # CONFIG_NVRAM is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
 
 #
@@ -863,6 +893,7 @@
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -870,6 +901,7 @@
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
@@ -952,6 +984,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -1028,6 +1065,7 @@
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 CONFIG_USB_MON=y
 
@@ -1179,9 +1217,6 @@
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_JFFS_FS=y
-CONFIG_JFFS_FS_VERBOSE=0
-# CONFIG_JFFS_PROC_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
@@ -1191,7 +1226,7 @@
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-# CONFIG_CRAMFS is not set
+CONFIG_CRAMFS=y
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
@@ -1285,6 +1320,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1296,6 +1336,8 @@
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_DETECT_SOFTLOCKUP=y
@@ -1311,12 +1353,10 @@
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
 CONFIG_FORCED_INLINING=y
-# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_ERRORS is not set
@@ -1339,6 +1379,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
@@ -1346,3 +1387,4 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 1b935fb..bb28087 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -18,6 +18,7 @@
 obj-$(CONFIG_ISA_DMA)		+= dma-isa.o
 obj-$(CONFIG_PCI)		+= bios32.o isa.o
 obj-$(CONFIG_SMP)		+= smp.o
+obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
 obj-$(CONFIG_OABI_COMPAT)	+= sys_oabi-compat.o
 
 obj-$(CONFIG_CRUNCH)		+= crunch.o crunch-bits.o
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index f7598cb..ae89cdd 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -356,6 +356,7 @@
 		CALL(sys_move_pages)
 /* 345 */	CALL(sys_getcpu)
 		CALL(sys_ni_syscall)		/* eventually epoll_pwait */
+		CALL(sys_kexec_load)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c
index cec8378..627d794 100644
--- a/arch/arm/kernel/crunch.c
+++ b/arch/arm/kernel/crunch.c
@@ -75,6 +75,7 @@
 static int __init crunch_init(void)
 {
 	thread_register_notifier(&crunch_notifier_block);
+	elf_hwcap |= HWCAP_CRUNCH;
 
 	return 0;
 }
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index 71257e3..f1c0fb9 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -1009,7 +1009,7 @@
 		ec->fiqmask = 4;
 	}
 
-	for (i = 0; i < sizeof(blacklist) / sizeof(*blacklist); i++)
+	for (i = 0; i < ARRAY_SIZE(blacklist); i++)
 		if (blacklist[i].manufacturer == ec->cid.manufacturer &&
 		    blacklist[i].product == ec->cid.product) {
 			ec->card_desc = blacklist[i].type;
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 8517c3c..cc10a09 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -99,7 +99,6 @@
 					@ cpsr_<exception>, "old_r0"
 
 	mov	r0, sp
-	and	r2, r6, #0x1f
 	b	bad_mode
 
 /*
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
new file mode 100644
index 0000000..863c664
--- /dev/null
+++ b/arch/arm/kernel/machine_kexec.c
@@ -0,0 +1,78 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ */
+
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/cacheflush.h>
+#include <asm/mach-types.h>
+
+const extern unsigned char relocate_new_kernel[];
+const extern unsigned int relocate_new_kernel_size;
+
+extern void setup_mm_for_reboot(char mode);
+
+extern unsigned long kexec_start_address;
+extern unsigned long kexec_indirection_page;
+extern unsigned long kexec_mach_type;
+
+/*
+ * Provide a dummy crash_notes definition while crash dump arrives to arm.
+ * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
+ */
+
+int machine_kexec_prepare(struct kimage *image)
+{
+	return 0;
+}
+
+void machine_kexec_cleanup(struct kimage *image)
+{
+}
+
+void machine_shutdown(void)
+{
+}
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+}
+
+void machine_kexec(struct kimage *image)
+{
+	unsigned long page_list;
+	unsigned long reboot_code_buffer_phys;
+	void *reboot_code_buffer;
+
+
+	page_list = image->head & PAGE_MASK;
+
+	/* we need both effective and real address here */
+	reboot_code_buffer_phys =
+	    page_to_pfn(image->control_code_page) << PAGE_SHIFT;
+	reboot_code_buffer = page_address(image->control_code_page);
+
+	/* Prepare parameters for reboot_code_buffer*/
+	kexec_start_address = image->start;
+	kexec_indirection_page = page_list;
+	kexec_mach_type = machine_arch_type;
+
+	/* copy our kernel relocation code to the control code page */
+	memcpy(reboot_code_buffer,
+	       relocate_new_kernel, relocate_new_kernel_size);
+
+
+	flush_icache_range((unsigned long) reboot_code_buffer,
+			   (unsigned long) reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE);
+	printk(KERN_INFO "Bye!\n");
+
+	cpu_proc_fin();
+	setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
+	cpu_reset(reboot_code_buffer_phys);
+}
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index a9e8f7e..782af3c 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -36,7 +36,13 @@
 #include <asm/uaccess.h>
 #include <asm/mach/time.h>
 
-extern const char *processor_modes[];
+static const char *processor_modes[] = {
+  "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
+  "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
+  "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" ,
+  "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
+};
+
 extern void setup_mm_for_reboot(char mode);
 
 static volatile int hlt_counter;
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
new file mode 100644
index 0000000..7baadae
--- /dev/null
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -0,0 +1,74 @@
+/*
+ * relocate_kernel.S - put the kernel image in place to boot
+ */
+
+#include <asm/kexec.h>
+
+	.globl relocate_new_kernel
+relocate_new_kernel:
+
+	ldr	r0,kexec_indirection_page
+	ldr	r1,kexec_start_address
+
+
+0:	/* top, read another word for the indirection page */
+	ldr	r3, [r0],#4
+
+	/* Is it a destination page. Put destination address to r4 */
+	tst	r3,#1,0
+	beq	1f
+	bic	r4,r3,#1
+	b	0b
+1:
+	/* Is it an indirection page */
+	tst	r3,#2,0
+	beq	1f
+	bic	r0,r3,#2
+	b	0b
+1:
+
+	/* are we done ? */
+	tst	r3,#4,0
+	beq	1f
+	b	2f
+
+1:
+	/* is it source ? */
+	tst	r3,#8,0
+	beq	0b
+	bic r3,r3,#8
+	mov r6,#1024
+9:
+	ldr r5,[r3],#4
+	str r5,[r4],#4
+	subs r6,r6,#1
+	bne 9b
+	b 0b
+
+2:
+	/* Jump to relocated kernel */
+	mov lr,r1
+	mov r0,#0
+	ldr r1,kexec_mach_type
+	mov r2,#0
+	mov pc,lr
+
+	.globl kexec_start_address
+kexec_start_address:
+	.long	0x0
+
+	.globl kexec_indirection_page
+kexec_indirection_page:
+	.long	0x0
+
+	.globl kexec_mach_type
+kexec_mach_type:
+	.long	0x0
+
+relocate_new_kernel_end:
+
+	.globl relocate_new_kernel_size
+relocate_new_kernel_size:
+	.long relocate_new_kernel_end - relocate_new_kernel
+
+
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index ed52215..03e37af 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -88,6 +88,9 @@
 #ifdef MULTI_CACHE
 struct cpu_cache_fns cpu_cache;
 #endif
+#ifdef CONFIG_OUTER_CACHE
+struct outer_cache_fns outer_cache;
+#endif
 
 struct stack {
 	u32 irq[3];
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index ee47c53..f61decb 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -40,12 +40,14 @@
  */
 struct sys_timer *system_timer;
 
+#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
 /* this needs a better home */
 DEFINE_SPINLOCK(rtc_lock);
 
-#ifdef CONFIG_SA1100_RTC_MODULE
+#ifdef CONFIG_RTC_DRV_CMOS_MODULE
 EXPORT_SYMBOL(rtc_lock);
 #endif
+#endif	/* pc-style 'CMOS' RTC support */
 
 /* change this if you have some constant time drift */
 #define USECS_PER_JIFFY	(1000000/HZ)
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 9089156..2409560 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -32,13 +32,6 @@
 #include "ptrace.h"
 #include "signal.h"
 
-const char *processor_modes[]=
-{ "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
-  "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
-  "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" ,
-  "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
-};
-
 static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
 
 #ifdef CONFIG_DEBUG_USER
@@ -289,7 +282,10 @@
 	regs->ARM_pc -= correction;
 
 	pc = (void __user *)instruction_pointer(regs);
-	if (thumb_mode(regs)) {
+
+	if (processor_mode(regs) == SVC_MODE) {
+		instr = *(u32 *) pc;
+	} else if (thumb_mode(regs)) {
 		get_user(instr, (u16 __user *)pc);
 	} else {
 		get_user(instr, (u32 __user *)pc);
@@ -337,12 +333,11 @@
  * It never returns, and never tries to sync.  We hope that we can at least
  * dump out some state information...
  */
-asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
+asmlinkage void bad_mode(struct pt_regs *regs, int reason)
 {
 	console_verbose();
 
-	printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n",
-		handler[reason], processor_modes[proc_mode]);
+	printk(KERN_CRIT "Bad mode in %s handler detected\n", handler[reason]);
 
 	die("Oops - bad mode", regs, 0);
 	local_irq_disable();
diff --git a/arch/arm/mach-at91rm9200/Kconfig b/arch/arm/mach-at91/Kconfig
similarity index 76%
rename from arch/arm/mach-at91rm9200/Kconfig
rename to arch/arm/mach-at91/Kconfig
index 9f11db8..bf0d962 100644
--- a/arch/arm/mach-at91rm9200/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -9,11 +9,14 @@
 	bool "AT91RM9200"
 
 config ARCH_AT91SAM9260
-	bool "AT91SAM9260"
+	bool "AT91SAM9260 or AT91SAM9XE"
 
 config ARCH_AT91SAM9261
 	bool "AT91SAM9261"
 
+config ARCH_AT91SAM9263
+	bool "AT91SAM9263"
+
 endchoice
 
 # ----------------------------------------------------------
@@ -90,13 +93,22 @@
 
 if ARCH_AT91SAM9260
 
-comment "AT91SAM9260 Board Type"
+comment "AT91SAM9260 Variants"
 
-config MACH_AT91SAM9260EK
-	bool "Atmel AT91SAM9260-EK Evaluation Kit"
+config ARCH_AT91SAM9260_SAM9XE
+	bool "AT91SAM9XE"
 	depends on ARCH_AT91SAM9260
 	help
-	  Select this if you are using Atmel's AT91SAM9260-EK Evaluation Kit.
+	  Select this if you are using Atmel's AT91SAM9XE System-on-Chip.
+	  They are basicaly AT91SAM9260s with various sizes of embedded Flash.
+
+comment "AT91SAM9260 / AT91SAM9XE Board Type"
+
+config MACH_AT91SAM9260EK
+	bool "Atmel AT91SAM9260-EK / AT91SAM9XE Evaluation Kit"
+	depends on ARCH_AT91SAM9260
+	help
+	  Select this if you are using Atmel's AT91SAM9260-EK or AT91SAM9XE Evaluation Kit
 	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933>
 
 endif
@@ -118,17 +130,32 @@
 
 # ----------------------------------------------------------
 
+if ARCH_AT91SAM9263
+
+comment "AT91SAM9263 Board Type"
+
+config MACH_AT91SAM9263EK
+	bool "Atmel AT91SAM9263-EK Evaluation Kit"
+	depends on ARCH_AT91SAM9263
+	help
+	  Select this if you are using Atmel's AT91SAM9263-EK Evaluation Kit.
+	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4057>
+
+endif
+
+# ----------------------------------------------------------
+
 comment "AT91 Board Options"
 
 config MTD_AT91_DATAFLASH_CARD
 	bool "Enable DataFlash Card support"
-	depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK)
+	depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK)
 	help
 	  Enable support for the DataFlash card.
 
 config MTD_NAND_AT91_BUSWIDTH_16
 	bool "Enable 16-bit data bus interface to NAND flash"
-	depends on (MACH_AT91SAM9261EK || MACH_AT91SAM9260EK)
+	depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK)
 	help
 	  On AT91SAM926x boards both types of NAND flash can be present
 	  (8 and 16 bit data bus width).
diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91/Makefile
similarity index 88%
rename from arch/arm/mach-at91rm9200/Makefile
rename to arch/arm/mach-at91/Makefile
index cf77700..05de6cd 100644
--- a/arch/arm/mach-at91rm9200/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -13,6 +13,7 @@
 obj-$(CONFIG_ARCH_AT91RM9200)	+= at91rm9200.o at91rm9200_time.o at91rm9200_devices.o
 obj-$(CONFIG_ARCH_AT91SAM9260)	+= at91sam9260.o at91sam926x_time.o at91sam9260_devices.o
 obj-$(CONFIG_ARCH_AT91SAM9261)	+= at91sam9261.o at91sam926x_time.o at91sam9261_devices.o
+obj-$(CONFIG_ARCH_AT91SAM9263)	+= at91sam9263.o at91sam926x_time.o at91sam9263_devices.o
 
 # AT91RM9200 board-specific support
 obj-$(CONFIG_MACH_ONEARM)	+= board-1arm.o
@@ -31,6 +32,9 @@
 # AT91SAM9261 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o
 
+# AT91SAM9263 board-specific support
+obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o
+
 # LEDs support
 led-$(CONFIG_ARCH_AT91RM9200DK)	+= leds.o
 led-$(CONFIG_MACH_AT91RM9200EK)	+= leds.o
diff --git a/arch/arm/mach-at91rm9200/Makefile.boot b/arch/arm/mach-at91/Makefile.boot
similarity index 100%
rename from arch/arm/mach-at91rm9200/Makefile.boot
rename to arch/arm/mach-at91/Makefile.boot
diff --git a/arch/arm/mach-at91rm9200/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
similarity index 89%
rename from arch/arm/mach-at91rm9200/at91rm9200.c
rename to arch/arm/mach-at91/at91rm9200.c
index a92e9a4..2ddcdd6 100644
--- a/arch/arm/mach-at91rm9200/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -1,5 +1,5 @@
 /*
- * arch/arm/mach-at91rm9200/at91rm9200.c
+ * arch/arm/mach-at91/at91rm9200.c
  *
  *  Copyright (C) 2005 SAN People
  *
@@ -117,6 +117,36 @@
 	.pmc_mask	= 1 << AT91RM9200_ID_PIOD,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
+static struct clk tc0_clk = {
+	.name		= "tc0_clk",
+	.pmc_mask	= 1 << AT91RM9200_ID_TC0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc1_clk = {
+	.name		= "tc1_clk",
+	.pmc_mask	= 1 << AT91RM9200_ID_TC1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc2_clk = {
+	.name		= "tc2_clk",
+	.pmc_mask	= 1 << AT91RM9200_ID_TC2,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc3_clk = {
+	.name		= "tc3_clk",
+	.pmc_mask	= 1 << AT91RM9200_ID_TC3,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc4_clk = {
+	.name		= "tc4_clk",
+	.pmc_mask	= 1 << AT91RM9200_ID_TC4,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc5_clk = {
+	.name		= "tc5_clk",
+	.pmc_mask	= 1 << AT91RM9200_ID_TC5,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
 
 static struct clk *periph_clocks[] __initdata = {
 	&pioA_clk,
@@ -132,7 +162,12 @@
 	&twi_clk,
 	&spi_clk,
 	// ssc 0 .. ssc2
-	// tc0 .. tc5
+	&tc0_clk,
+	&tc1_clk,
+	&tc2_clk,
+	&tc3_clk,
+	&tc4_clk,
+	&tc5_clk,
 	&ohci_clk,
 	&ether_clk,
 	// irq0 .. irq6
diff --git a/arch/arm/mach-at91rm9200/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
similarity index 98%
rename from arch/arm/mach-at91rm9200/at91rm9200_devices.c
rename to arch/arm/mach-at91/at91rm9200_devices.c
index 57fac72..2624a4f 100644
--- a/arch/arm/mach-at91rm9200/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -1,5 +1,5 @@
 /*
- * arch/arm/mach-at91rm9200/at91rm9200_devices.c
+ * arch/arm/mach-at91/at91rm9200_devices.c
  *
  *  Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
  *  Copyright (C) 2005 David Brownell
@@ -315,7 +315,7 @@
 	.num_resources	= ARRAY_SIZE(mmc_resources),
 };
 
-void __init at91_add_device_mmc(struct at91_mmc_data *data)
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
 {
 	if (!data)
 		return;
@@ -361,7 +361,7 @@
 	platform_device_register(&at91rm9200_mmc_device);
 }
 #else
-void __init at91_add_device_mmc(struct at91_mmc_data *data) {}
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
 #endif
 
 
@@ -594,6 +594,10 @@
 
 void __init at91_init_leds(u8 cpu_led, u8 timer_led)
 {
+	/* Enable GPIO to access the LEDs */
+	at91_set_gpio_output(cpu_led, 1);
+	at91_set_gpio_output(timer_led, 1);
+
 	at91_leds_cpu	= cpu_led;
 	at91_leds_timer	= timer_led;
 }
diff --git a/arch/arm/mach-at91rm9200/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
similarity index 98%
rename from arch/arm/mach-at91rm9200/at91rm9200_time.c
rename to arch/arm/mach-at91/at91rm9200_time.c
index b999e19..949199a 100644
--- a/arch/arm/mach-at91rm9200/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/at91rm9200_time.c
+ * linux/arch/arm/mach-at91/at91rm9200_time.c
  *
  *  Copyright (C) 2003 SAN People
  *  Copyright (C) 2003 ATMEL
diff --git a/arch/arm/mach-at91rm9200/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
similarity index 79%
rename from arch/arm/mach-at91rm9200/at91sam9260.c
rename to arch/arm/mach-at91/at91sam9260.c
index b14871a..6ea41d8 100644
--- a/arch/arm/mach-at91rm9200/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -1,5 +1,5 @@
 /*
- * arch/arm/mach-at91rm9200/at91sam9260.c
+ * arch/arm/mach-at91/at91sam9260.c
  *
  *  Copyright (C) 2006 SAN People
  *
@@ -14,6 +14,7 @@
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <asm/arch/cpu.h>
 #include <asm/arch/at91sam9260.h>
 #include <asm/arch/at91_pmc.h>
 #include <asm/arch/at91_rstc.h>
@@ -27,7 +28,11 @@
 		.pfn		= __phys_to_pfn(AT91_BASE_SYS),
 		.length		= SZ_16K,
 		.type		= MT_DEVICE,
-	}, {
+	}
+};
+
+static struct map_desc at91sam9260_sram_desc[] __initdata = {
+	{
 		.virtual	= AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE,
 		.pfn		= __phys_to_pfn(AT91SAM9260_SRAM0_BASE),
 		.length		= AT91SAM9260_SRAM0_SIZE,
@@ -37,7 +42,14 @@
 		.pfn		= __phys_to_pfn(AT91SAM9260_SRAM1_BASE),
 		.length		= AT91SAM9260_SRAM1_SIZE,
 		.type		= MT_DEVICE,
-	},
+	}
+};
+
+static struct map_desc at91sam9xe_sram_desc[] __initdata = {
+	{
+		.pfn		= __phys_to_pfn(AT91SAM9XE_SRAM_BASE),
+		.type		= MT_DEVICE,
+	}
 };
 
 /* --------------------------------------------------------------------
@@ -107,13 +119,28 @@
 	.pmc_mask	= 1 << AT91SAM9260_ID_SPI1,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
+static struct clk tc0_clk = {
+	.name		= "tc0_clk",
+	.pmc_mask	= 1 << AT91SAM9260_ID_TC0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc1_clk = {
+	.name		= "tc1_clk",
+	.pmc_mask	= 1 << AT91SAM9260_ID_TC1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc2_clk = {
+	.name		= "tc2_clk",
+	.pmc_mask	= 1 << AT91SAM9260_ID_TC2,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
 static struct clk ohci_clk = {
 	.name		= "ohci_clk",
 	.pmc_mask	= 1 << AT91SAM9260_ID_UHP,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
-static struct clk ether_clk = {
-	.name		= "ether_clk",
+static struct clk macb_clk = {
+	.name		= "macb_clk",
 	.pmc_mask	= 1 << AT91SAM9260_ID_EMAC,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
@@ -137,6 +164,21 @@
 	.pmc_mask	= 1 << AT91SAM9260_ID_US5,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
+static struct clk tc3_clk = {
+	.name		= "tc3_clk",
+	.pmc_mask	= 1 << AT91SAM9260_ID_TC3,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc4_clk = {
+	.name		= "tc4_clk",
+	.pmc_mask	= 1 << AT91SAM9260_ID_TC4,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc5_clk = {
+	.name		= "tc5_clk",
+	.pmc_mask	= 1 << AT91SAM9260_ID_TC5,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
 
 static struct clk *periph_clocks[] __initdata = {
 	&pioA_clk,
@@ -152,14 +194,18 @@
 	&spi0_clk,
 	&spi1_clk,
 	// ssc
-	// tc0 .. tc2
+	&tc0_clk,
+	&tc1_clk,
+	&tc2_clk,
 	&ohci_clk,
-	&ether_clk,
+	&macb_clk,
 	&isi_clk,
 	&usart3_clk,
 	&usart4_clk,
 	&usart5_clk,
-	// tc3 .. tc5
+	&tc3_clk,
+	&tc4_clk,
+	&tc5_clk,
 	// irq0 .. irq2
 };
 
@@ -213,7 +259,7 @@
 
 static void at91sam9260_reset(void)
 {
-	at91_sys_write(AT91_RSTC_CR, (0xA5 << 24) | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
+	at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
 }
 
 
@@ -221,11 +267,37 @@
  *  AT91SAM9260 processor initialization
  * -------------------------------------------------------------------- */
 
+static void __init at91sam9xe_initialize(void)
+{
+	unsigned long cidr, sram_size;
+
+	cidr = at91_sys_read(AT91_DBGU_CIDR);
+
+	switch (cidr & AT91_CIDR_SRAMSIZ) {
+		case AT91_CIDR_SRAMSIZ_32K:
+			sram_size = 2 * SZ_16K;
+			break;
+		case AT91_CIDR_SRAMSIZ_16K:
+		default:
+			sram_size = SZ_16K;
+	}
+
+	at91sam9xe_sram_desc->virtual = AT91_IO_VIRT_BASE - sram_size;
+	at91sam9xe_sram_desc->length = sram_size;
+
+	iotable_init(at91sam9xe_sram_desc, ARRAY_SIZE(at91sam9xe_sram_desc));
+}
+
 void __init at91sam9260_initialize(unsigned long main_clock)
 {
 	/* Map peripherals */
 	iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc));
 
+	if (cpu_is_at91sam9xe())
+		at91sam9xe_initialize();
+	else
+		iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc));
+
 	at91_arch_reset = at91sam9260_reset;
 	at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
 			| (1 << AT91SAM9260_ID_IRQ2);
diff --git a/arch/arm/mach-at91rm9200/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
similarity index 97%
rename from arch/arm/mach-at91rm9200/at91sam9260_devices.c
rename to arch/arm/mach-at91/at91sam9260_devices.c
index f42d3a4..f7d342c 100644
--- a/arch/arm/mach-at91rm9200/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -1,5 +1,5 @@
 /*
- * arch/arm/mach-at91rm9200/at91sam9260_devices.c
+ * arch/arm/mach-at91/at91sam9260_devices.c
  *
  *  Copyright (C) 2006 Atmel
  *
@@ -128,7 +128,7 @@
 
 #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
 static u64 eth_dmamask = 0xffffffffUL;
-static struct eth_platform_data eth_data;
+static struct at91_eth_data eth_data;
 
 static struct resource eth_resources[] = {
 	[0] = {
@@ -155,7 +155,7 @@
 	.num_resources	= ARRAY_SIZE(eth_resources),
 };
 
-void __init at91_add_device_eth(struct eth_platform_data *data)
+void __init at91_add_device_eth(struct at91_eth_data *data)
 {
 	if (!data)
 		return;
@@ -192,7 +192,7 @@
 	platform_device_register(&at91sam9260_eth_device);
 }
 #else
-void __init at91_add_device_eth(struct eth_platform_data *data) {}
+void __init at91_add_device_eth(struct at91_eth_data *data) {}
 #endif
 
 
@@ -229,7 +229,7 @@
 	.num_resources	= ARRAY_SIZE(mmc_resources),
 };
 
-void __init at91_add_device_mmc(struct at91_mmc_data *data)
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
 {
 	if (!data)
 		return;
@@ -275,7 +275,7 @@
 	platform_device_register(&at91sam9260_mmc_device);
 }
 #else
-void __init at91_add_device_mmc(struct at91_mmc_data *data) {}
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
 #endif
 
 
@@ -515,6 +515,10 @@
 
 void __init at91_init_leds(u8 cpu_led, u8 timer_led)
 {
+	/* Enable GPIO to access the LEDs */
+	at91_set_gpio_output(cpu_led, 1);
+	at91_set_gpio_output(timer_led, 1);
+
 	at91_leds_cpu	= cpu_led;
 	at91_leds_timer	= timer_led;
 }
diff --git a/arch/arm/mach-at91rm9200/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
similarity index 92%
rename from arch/arm/mach-at91rm9200/at91sam9261.c
rename to arch/arm/mach-at91/at91sam9261.c
index d242bb8..784d1e6 100644
--- a/arch/arm/mach-at91rm9200/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -1,5 +1,5 @@
 /*
- * arch/arm/mach-at91rm9200/at91sam9261.c
+ * arch/arm/mach-at91/at91sam9261.c
  *
  *  Copyright (C) 2005 SAN People
  *
@@ -97,6 +97,21 @@
 	.pmc_mask	= 1 << AT91SAM9261_ID_SPI1,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
+static struct clk tc0_clk = {
+	.name		= "tc0_clk",
+	.pmc_mask	= 1 << AT91SAM9261_ID_TC0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc1_clk = {
+	.name		= "tc1_clk",
+	.pmc_mask	= 1 << AT91SAM9261_ID_TC1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc2_clk = {
+	.name		= "tc2_clk",
+	.pmc_mask	= 1 << AT91SAM9261_ID_TC2,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
 static struct clk ohci_clk = {
 	.name		= "ohci_clk",
 	.pmc_mask	= 1 << AT91SAM9261_ID_UHP,
@@ -121,7 +136,9 @@
 	&spi0_clk,
 	&spi1_clk,
 	// ssc 0 .. ssc2
-	// tc0 .. tc2
+	&tc0_clk,
+	&tc1_clk,
+	&tc2_clk,
 	&ohci_clk,
 	&lcdc_clk,
 	// irq0 .. irq2
@@ -208,7 +225,7 @@
 
 static void at91sam9261_reset(void)
 {
-	at91_sys_write(AT91_RSTC_CR, (0xA5 << 24) | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
+	at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
 }
 
 
diff --git a/arch/arm/mach-at91rm9200/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
similarity index 98%
rename from arch/arm/mach-at91rm9200/at91sam9261_devices.c
rename to arch/arm/mach-at91/at91sam9261_devices.c
index ed1d790..e150476 100644
--- a/arch/arm/mach-at91rm9200/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -1,5 +1,5 @@
 /*
- * arch/arm/mach-at91rm9200/at91sam9261_devices.c
+ * arch/arm/mach-at91/at91sam9261_devices.c
  *
  *  Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
  *  Copyright (C) 2005 David Brownell
@@ -159,7 +159,7 @@
 	.num_resources	= ARRAY_SIZE(mmc_resources),
 };
 
-void __init at91_add_device_mmc(struct at91_mmc_data *data)
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
 {
 	if (!data)
 		return;
@@ -192,7 +192,7 @@
 	platform_device_register(&at91sam9261_mmc_device);
 }
 #else
-void __init at91_add_device_mmc(struct at91_mmc_data *data) {}
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
 #endif
 
 
@@ -513,6 +513,10 @@
 
 void __init at91_init_leds(u8 cpu_led, u8 timer_led)
 {
+	/* Enable GPIO to access the LEDs */
+	at91_set_gpio_output(cpu_led, 1);
+	at91_set_gpio_output(timer_led, 1);
+
 	at91_leds_cpu	= cpu_led;
 	at91_leds_timer	= timer_led;
 }
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
new file mode 100644
index 0000000..6aa342e
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -0,0 +1,313 @@
+/*
+ * arch/arm/mach-at91/at91sam9263.c
+ *
+ *  Copyright (C) 2007 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/arch/at91sam9263.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91_rstc.h>
+
+#include "generic.h"
+#include "clock.h"
+
+static struct map_desc at91sam9263_io_desc[] __initdata = {
+	{
+		.virtual	= AT91_VA_BASE_SYS,
+		.pfn		= __phys_to_pfn(AT91_BASE_SYS),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE,
+		.pfn		= __phys_to_pfn(AT91SAM9263_SRAM0_BASE),
+		.length		= AT91SAM9263_SRAM0_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE - AT91SAM9263_SRAM1_SIZE,
+		.pfn		= __phys_to_pfn(AT91SAM9263_SRAM1_BASE),
+		.length		= AT91SAM9263_SRAM1_SIZE,
+		.type		= MT_DEVICE,
+	},
+};
+
+/* --------------------------------------------------------------------
+ *  Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk pioA_clk = {
+	.name		= "pioA_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_PIOA,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioB_clk = {
+	.name		= "pioB_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_PIOB,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioCDE_clk = {
+	.name		= "pioCDE_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_PIOCDE,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+	.name		= "usart0_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_US0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+	.name		= "usart1_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_US1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+	.name		= "usart2_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_US2,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc0_clk = {
+	.name		= "mci0_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_MCI0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc1_clk = {
+	.name		= "mci1_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_MCI1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi_clk = {
+	.name		= "twi_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_TWI,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi0_clk = {
+	.name		= "spi0_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_SPI0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi1_clk = {
+	.name		= "spi1_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_SPI1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tcb_clk = {
+	.name		= "tcb_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_TCB,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk macb_clk = {
+	.name		= "macb_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_EMAC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk udc_clk = {
+	.name		= "udc_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_UDP,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk isi_clk = {
+	.name		= "isi_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_ISI,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk lcdc_clk = {
+	.name		= "lcdc_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_ISI,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ohci_clk = {
+	.name		= "ohci_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_UHP,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+
+static struct clk *periph_clocks[] __initdata = {
+	&pioA_clk,
+	&pioB_clk,
+	&pioCDE_clk,
+	&usart0_clk,
+	&usart1_clk,
+	&usart2_clk,
+	&mmc0_clk,
+	&mmc1_clk,
+	// can
+	&twi_clk,
+	&spi0_clk,
+	&spi1_clk,
+	// ssc0 .. ssc1
+	// ac97
+	&tcb_clk,
+	// pwmc
+	&macb_clk,
+	// 2dge
+	&udc_clk,
+	&isi_clk,
+	&lcdc_clk,
+	// dma
+	&ohci_clk,
+	// irq0 .. irq1
+};
+
+/*
+ * The four programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+	.name		= "pck0",
+	.pmc_mask	= AT91_PMC_PCK0,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 0,
+};
+static struct clk pck1 = {
+	.name		= "pck1",
+	.pmc_mask	= AT91_PMC_PCK1,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 1,
+};
+static struct clk pck2 = {
+	.name		= "pck2",
+	.pmc_mask	= AT91_PMC_PCK2,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 2,
+};
+static struct clk pck3 = {
+	.name		= "pck3",
+	.pmc_mask	= AT91_PMC_PCK3,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 3,
+};
+
+static void __init at91sam9263_register_clocks(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+		clk_register(periph_clocks[i]);
+
+	clk_register(&pck0);
+	clk_register(&pck1);
+	clk_register(&pck2);
+	clk_register(&pck3);
+}
+
+/* --------------------------------------------------------------------
+ *  GPIO
+ * -------------------------------------------------------------------- */
+
+static struct at91_gpio_bank at91sam9263_gpio[] = {
+	{
+		.id		= AT91SAM9263_ID_PIOA,
+		.offset		= AT91_PIOA,
+		.clock		= &pioA_clk,
+	}, {
+		.id		= AT91SAM9263_ID_PIOB,
+		.offset		= AT91_PIOB,
+		.clock		= &pioB_clk,
+	}, {
+		.id		= AT91SAM9263_ID_PIOCDE,
+		.offset		= AT91_PIOC,
+		.clock		= &pioCDE_clk,
+	}, {
+		.id		= AT91SAM9263_ID_PIOCDE,
+		.offset		= AT91_PIOD,
+		.clock		= &pioCDE_clk,
+	}, {
+		.id		= AT91SAM9263_ID_PIOCDE,
+		.offset		= AT91_PIOE,
+		.clock		= &pioCDE_clk,
+	}
+};
+
+static void at91sam9263_reset(void)
+{
+	at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
+}
+
+
+/* --------------------------------------------------------------------
+ *  AT91SAM9263 processor initialization
+ * -------------------------------------------------------------------- */
+
+void __init at91sam9263_initialize(unsigned long main_clock)
+{
+	/* Map peripherals */
+	iotable_init(at91sam9263_io_desc, ARRAY_SIZE(at91sam9263_io_desc));
+
+	at91_arch_reset = at91sam9263_reset;
+	at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1);
+
+	/* Init clock subsystem */
+	at91_clock_init(main_clock);
+
+	/* Register the processor-specific clocks */
+	at91sam9263_register_clocks();
+
+	/* Register GPIO subsystem */
+	at91_gpio_init(at91sam9263_gpio, 5);
+}
+
+/* --------------------------------------------------------------------
+ *  Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = {
+	7,	/* Advanced Interrupt Controller (FIQ) */
+	7,	/* System Peripherals */
+	0,	/* Parallel IO Controller A */
+	0,	/* Parallel IO Controller B */
+	0,	/* Parallel IO Controller C, D and E */
+	0,
+	0,
+	6,	/* USART 0 */
+	6,	/* USART 1 */
+	6,	/* USART 2 */
+	0,	/* Multimedia Card Interface 0 */
+	0,	/* Multimedia Card Interface 1 */
+	4,	/* CAN */
+	0,	/* Two-Wire Interface */
+	6,	/* Serial Peripheral Interface 0 */
+	6,	/* Serial Peripheral Interface 1 */
+	5,	/* Serial Synchronous Controller 0 */
+	5,	/* Serial Synchronous Controller 1 */
+	6,	/* AC97 Controller */
+	0,	/* Timer Counter 0, 1 and 2 */
+	0,	/* Pulse Width Modulation Controller */
+	3,	/* Ethernet */
+	0,
+	0,	/* 2D Graphic Engine */
+	3,	/* USB Device Port */
+	0,	/* Image Sensor Interface */
+	3,	/* LDC Controller */
+	0,	/* DMA Controller */
+	0,
+	3,	/* USB Host port */
+	0,	/* Advanced Interrupt Controller (IRQ0) */
+	0,	/* Advanced Interrupt Controller (IRQ1) */
+};
+
+void __init at91sam9263_init_interrupts(unsigned int priority[NR_AIC_IRQS])
+{
+	if (!priority)
+		priority = at91sam9263_default_irq_priority;
+
+	/* Initialize the AIC interrupt controller */
+	at91_aic_init(priority);
+
+	/* Enable GPIO interrupts */
+	at91_gpio_irq_setup();
+}
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
new file mode 100644
index 0000000..d9af7ca
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -0,0 +1,818 @@
+/*
+ * arch/arm/mach-at91/at91sam9263_devices.c
+ *
+ *  Copyright (C) 2007 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/platform_device.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/at91sam9263.h>
+#include <asm/arch/at91sam926x_mc.h>
+#include <asm/arch/at91sam9263_matrix.h>
+
+#include "generic.h"
+
+#define SZ_512	0x00000200
+#define SZ_256	0x00000100
+#define SZ_16	0x00000010
+
+/* --------------------------------------------------------------------
+ *  USB Host
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static u64 ohci_dmamask = 0xffffffffUL;
+static struct at91_usbh_data usbh_data;
+
+static struct resource usbh_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_UHP_BASE,
+		.end	= AT91SAM9263_UHP_BASE + SZ_1M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_UHP,
+		.end	= AT91SAM9263_ID_UHP,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91_usbh_device = {
+	.name		= "at91_ohci",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &ohci_dmamask,
+				.coherent_dma_mask	= 0xffffffff,
+				.platform_data		= &usbh_data,
+	},
+	.resource	= usbh_resources,
+	.num_resources	= ARRAY_SIZE(usbh_resources),
+};
+
+void __init at91_add_device_usbh(struct at91_usbh_data *data)
+{
+	int i;
+
+	if (!data)
+		return;
+
+	/* Enable VBus control for UHP ports */
+	for (i = 0; i < data->ports; i++) {
+		if (data->vbus_pin[i])
+			at91_set_gpio_output(data->vbus_pin[i], 0);
+	}
+
+	usbh_data = *data;
+	platform_device_register(&at91_usbh_device);
+}
+#else
+void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  USB Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_USB_GADGET_AT91
+static struct at91_udc_data udc_data;
+
+static struct resource udc_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_UDP,
+		.end	= AT91SAM9263_BASE_UDP + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_UDP,
+		.end	= AT91SAM9263_ID_UDP,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91_udc_device = {
+	.name		= "at91_udc",
+	.id		= -1,
+	.dev		= {
+				.platform_data		= &udc_data,
+	},
+	.resource	= udc_resources,
+	.num_resources	= ARRAY_SIZE(udc_resources),
+};
+
+void __init at91_add_device_udc(struct at91_udc_data *data)
+{
+	if (!data)
+		return;
+
+	if (data->vbus_pin) {
+		at91_set_gpio_input(data->vbus_pin, 0);
+		at91_set_deglitch(data->vbus_pin, 1);
+	}
+
+	/* Pullup pin is handled internally by USB device peripheral */
+
+	udc_data = *data;
+	platform_device_register(&at91_udc_device);
+}
+#else
+void __init at91_add_device_udc(struct at91_udc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  Ethernet
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
+static u64 eth_dmamask = 0xffffffffUL;
+static struct at91_eth_data eth_data;
+
+static struct resource eth_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_EMAC,
+		.end	= AT91SAM9263_BASE_EMAC + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_EMAC,
+		.end	= AT91SAM9263_ID_EMAC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9263_eth_device = {
+	.name		= "macb",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &eth_dmamask,
+				.coherent_dma_mask	= 0xffffffff,
+				.platform_data		= &eth_data,
+	},
+	.resource	= eth_resources,
+	.num_resources	= ARRAY_SIZE(eth_resources),
+};
+
+void __init at91_add_device_eth(struct at91_eth_data *data)
+{
+	if (!data)
+		return;
+
+	if (data->phy_irq_pin) {
+		at91_set_gpio_input(data->phy_irq_pin, 0);
+		at91_set_deglitch(data->phy_irq_pin, 1);
+	}
+
+	/* Pins used for MII and RMII */
+	at91_set_A_periph(AT91_PIN_PE21, 0);	/* ETXCK_EREFCK */
+	at91_set_B_periph(AT91_PIN_PC25, 0);	/* ERXDV */
+	at91_set_A_periph(AT91_PIN_PE25, 0);	/* ERX0 */
+	at91_set_A_periph(AT91_PIN_PE26, 0);	/* ERX1 */
+	at91_set_A_periph(AT91_PIN_PE27, 0);	/* ERXER */
+	at91_set_A_periph(AT91_PIN_PE28, 0);	/* ETXEN */
+	at91_set_A_periph(AT91_PIN_PE23, 0);	/* ETX0 */
+	at91_set_A_periph(AT91_PIN_PE24, 0);	/* ETX1 */
+	at91_set_A_periph(AT91_PIN_PE30, 0);	/* EMDIO */
+	at91_set_A_periph(AT91_PIN_PE29, 0);	/* EMDC */
+
+	if (!data->is_rmii) {
+		at91_set_A_periph(AT91_PIN_PE22, 0);	/* ECRS */
+		at91_set_B_periph(AT91_PIN_PC26, 0);	/* ECOL */
+		at91_set_B_periph(AT91_PIN_PC22, 0);	/* ERX2 */
+		at91_set_B_periph(AT91_PIN_PC23, 0);	/* ERX3 */
+		at91_set_B_periph(AT91_PIN_PC27, 0);	/* ERXCK */
+		at91_set_B_periph(AT91_PIN_PC20, 0);	/* ETX2 */
+		at91_set_B_periph(AT91_PIN_PC21, 0);	/* ETX3 */
+		at91_set_B_periph(AT91_PIN_PC24, 0);	/* ETXER */
+	}
+
+	eth_data = *data;
+	platform_device_register(&at91sam9263_eth_device);
+}
+#else
+void __init at91_add_device_eth(struct at91_eth_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  MMC / SD
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
+static u64 mmc_dmamask = 0xffffffffUL;
+static struct at91_mmc_data mmc0_data, mmc1_data;
+
+static struct resource mmc0_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_MCI0,
+		.end	= AT91SAM9263_BASE_MCI0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_MCI0,
+		.end	= AT91SAM9263_ID_MCI0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9263_mmc0_device = {
+	.name		= "at91_mci",
+	.id		= 0,
+	.dev		= {
+				.dma_mask		= &mmc_dmamask,
+				.coherent_dma_mask	= 0xffffffff,
+				.platform_data		= &mmc0_data,
+	},
+	.resource	= mmc0_resources,
+	.num_resources	= ARRAY_SIZE(mmc0_resources),
+};
+
+static struct resource mmc1_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_MCI1,
+		.end	= AT91SAM9263_BASE_MCI1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_MCI1,
+		.end	= AT91SAM9263_ID_MCI1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9263_mmc1_device = {
+	.name		= "at91_mci",
+	.id		= 1,
+	.dev		= {
+				.dma_mask		= &mmc_dmamask,
+				.coherent_dma_mask	= 0xffffffff,
+				.platform_data		= &mmc1_data,
+	},
+	.resource	= mmc1_resources,
+	.num_resources	= ARRAY_SIZE(mmc1_resources),
+};
+
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
+{
+	if (!data)
+		return;
+
+	/* input/irq */
+	if (data->det_pin) {
+		at91_set_gpio_input(data->det_pin, 1);
+		at91_set_deglitch(data->det_pin, 1);
+	}
+	if (data->wp_pin)
+		at91_set_gpio_input(data->wp_pin, 1);
+	if (data->vcc_pin)
+		at91_set_gpio_output(data->vcc_pin, 0);
+
+	if (mmc_id == 0) {		/* MCI0 */
+		/* CLK */
+		at91_set_A_periph(AT91_PIN_PA12, 0);
+
+		if (data->slot_b) {
+			/* CMD */
+			at91_set_A_periph(AT91_PIN_PA16, 1);
+
+			/* DAT0, maybe DAT1..DAT3 */
+			at91_set_A_periph(AT91_PIN_PA17, 1);
+			if (data->wire4) {
+				at91_set_A_periph(AT91_PIN_PA18, 1);
+				at91_set_A_periph(AT91_PIN_PA19, 1);
+				at91_set_A_periph(AT91_PIN_PA20, 1);
+			}
+		} else {
+			/* CMD */
+			at91_set_A_periph(AT91_PIN_PA1, 1);
+
+			/* DAT0, maybe DAT1..DAT3 */
+			at91_set_A_periph(AT91_PIN_PA0, 1);
+			if (data->wire4) {
+				at91_set_A_periph(AT91_PIN_PA3, 1);
+				at91_set_A_periph(AT91_PIN_PA4, 1);
+				at91_set_A_periph(AT91_PIN_PA5, 1);
+			}
+		}
+
+		mmc0_data = *data;
+		at91_clock_associate("mci0_clk", &at91sam9263_mmc1_device.dev, "mci_clk");
+		platform_device_register(&at91sam9263_mmc0_device);
+	} else {			/* MCI1 */
+		/* CLK */
+		at91_set_A_periph(AT91_PIN_PA6, 0);
+
+		if (data->slot_b) {
+			/* CMD */
+			at91_set_A_periph(AT91_PIN_PA21, 1);
+
+			/* DAT0, maybe DAT1..DAT3 */
+			at91_set_A_periph(AT91_PIN_PA22, 1);
+			if (data->wire4) {
+				at91_set_A_periph(AT91_PIN_PA23, 1);
+				at91_set_A_periph(AT91_PIN_PA24, 1);
+				at91_set_A_periph(AT91_PIN_PA25, 1);
+			}
+		} else {
+			/* CMD */
+			at91_set_A_periph(AT91_PIN_PA7, 1);
+
+			/* DAT0, maybe DAT1..DAT3 */
+			at91_set_A_periph(AT91_PIN_PA8, 1);
+			if (data->wire4) {
+				at91_set_A_periph(AT91_PIN_PA9, 1);
+				at91_set_A_periph(AT91_PIN_PA10, 1);
+				at91_set_A_periph(AT91_PIN_PA11, 1);
+			}
+		}
+
+		mmc1_data = *data;
+		at91_clock_associate("mci1_clk", &at91sam9263_mmc1_device.dev, "mci_clk");
+		platform_device_register(&at91sam9263_mmc1_device);
+	}
+}
+#else
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  NAND / SmartMedia
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE)
+static struct at91_nand_data nand_data;
+
+#define NAND_BASE	AT91_CHIPSELECT_3
+
+static struct resource nand_resources[] = {
+	{
+		.start	= NAND_BASE,
+		.end	= NAND_BASE + SZ_256M - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device at91sam9263_nand_device = {
+	.name		= "at91_nand",
+	.id		= -1,
+	.dev		= {
+				.platform_data	= &nand_data,
+	},
+	.resource	= nand_resources,
+	.num_resources	= ARRAY_SIZE(nand_resources),
+};
+
+void __init at91_add_device_nand(struct at91_nand_data *data)
+{
+	unsigned long csa, mode;
+
+	if (!data)
+		return;
+
+	csa = at91_sys_read(AT91_MATRIX_EBI0CSA);
+	at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC);
+
+	/* set the bus interface characteristics */
+	at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
+			| AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0));
+
+	at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3)
+			| AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3));
+
+	at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5));
+
+	if (data->bus_width_16)
+		mode = AT91_SMC_DBW_16;
+	else
+		mode = AT91_SMC_DBW_8;
+	at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2));
+
+	/* enable pin */
+	if (data->enable_pin)
+		at91_set_gpio_output(data->enable_pin, 1);
+
+	/* ready/busy pin */
+	if (data->rdy_pin)
+		at91_set_gpio_input(data->rdy_pin, 1);
+
+	/* card detect pin */
+	if (data->det_pin)
+		at91_set_gpio_input(data->det_pin, 1);
+
+	nand_data = *data;
+	platform_device_register(&at91sam9263_nand_device);
+}
+#else
+void __init at91_add_device_nand(struct at91_nand_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  TWI (i2c)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+
+static struct resource twi_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_TWI,
+		.end	= AT91SAM9263_BASE_TWI + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_TWI,
+		.end	= AT91SAM9263_ID_TWI,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9263_twi_device = {
+	.name		= "at91_i2c",
+	.id		= -1,
+	.resource	= twi_resources,
+	.num_resources	= ARRAY_SIZE(twi_resources),
+};
+
+void __init at91_add_device_i2c(void)
+{
+	/* pins used for TWI interface */
+	at91_set_A_periph(AT91_PIN_PB4, 0);		/* TWD */
+	at91_set_multi_drive(AT91_PIN_PB4, 1);
+
+	at91_set_A_periph(AT91_PIN_PB5, 0);		/* TWCK */
+	at91_set_multi_drive(AT91_PIN_PB5, 1);
+
+	platform_device_register(&at91sam9263_twi_device);
+}
+#else
+void __init at91_add_device_i2c(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  SPI
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+static u64 spi_dmamask = 0xffffffffUL;
+
+static struct resource spi0_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_SPI0,
+		.end	= AT91SAM9263_BASE_SPI0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_SPI0,
+		.end	= AT91SAM9263_ID_SPI0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9263_spi0_device = {
+	.name		= "atmel_spi",
+	.id		= 0,
+	.dev		= {
+				.dma_mask		= &spi_dmamask,
+				.coherent_dma_mask	= 0xffffffff,
+	},
+	.resource	= spi0_resources,
+	.num_resources	= ARRAY_SIZE(spi0_resources),
+};
+
+static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PB11 };
+
+static struct resource spi1_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_SPI1,
+		.end	= AT91SAM9263_BASE_SPI1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_SPI1,
+		.end	= AT91SAM9263_ID_SPI1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9263_spi1_device = {
+	.name		= "atmel_spi",
+	.id		= 1,
+	.dev		= {
+				.dma_mask		= &spi_dmamask,
+				.coherent_dma_mask	= 0xffffffff,
+	},
+	.resource	= spi1_resources,
+	.num_resources	= ARRAY_SIZE(spi1_resources),
+};
+
+static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 };
+
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+{
+	int i;
+	unsigned long cs_pin;
+	short enable_spi0 = 0;
+	short enable_spi1 = 0;
+
+	/* Choose SPI chip-selects */
+	for (i = 0; i < nr_devices; i++) {
+		if (devices[i].controller_data)
+			cs_pin = (unsigned long) devices[i].controller_data;
+		else if (devices[i].bus_num == 0)
+			cs_pin = spi0_standard_cs[devices[i].chip_select];
+		else
+			cs_pin = spi1_standard_cs[devices[i].chip_select];
+
+		if (devices[i].bus_num == 0)
+			enable_spi0 = 1;
+		else
+			enable_spi1 = 1;
+
+		/* enable chip-select pin */
+		at91_set_gpio_output(cs_pin, 1);
+
+		/* pass chip-select pin to driver */
+		devices[i].controller_data = (void *) cs_pin;
+	}
+
+	spi_register_board_info(devices, nr_devices);
+
+	/* Configure SPI bus(es) */
+	if (enable_spi0) {
+		at91_set_B_periph(AT91_PIN_PA0, 0);	/* SPI0_MISO */
+		at91_set_B_periph(AT91_PIN_PA1, 0);	/* SPI0_MOSI */
+		at91_set_B_periph(AT91_PIN_PA2, 0);	/* SPI1_SPCK */
+
+		at91_clock_associate("spi0_clk", &at91sam9263_spi0_device.dev, "spi_clk");
+		platform_device_register(&at91sam9263_spi0_device);
+	}
+	if (enable_spi1) {
+		at91_set_A_periph(AT91_PIN_PB12, 0);	/* SPI1_MISO */
+		at91_set_A_periph(AT91_PIN_PB13, 0);	/* SPI1_MOSI */
+		at91_set_A_periph(AT91_PIN_PB14, 0);	/* SPI1_SPCK */
+
+		at91_clock_associate("spi1_clk", &at91sam9263_spi1_device.dev, "spi_clk");
+		platform_device_register(&at91sam9263_spi1_device);
+	}
+}
+#else
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  LEDs
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_LEDS)
+u8 at91_leds_cpu;
+u8 at91_leds_timer;
+
+void __init at91_init_leds(u8 cpu_led, u8 timer_led)
+{
+	/* Enable GPIO to access the LEDs */
+	at91_set_gpio_output(cpu_led, 1);
+	at91_set_gpio_output(timer_led, 1);
+
+	at91_leds_cpu	= cpu_led;
+	at91_leds_timer	= timer_led;
+}
+#else
+void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  UART
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SERIAL_ATMEL)
+
+static struct resource dbgu_resources[] = {
+	[0] = {
+		.start	= AT91_VA_BASE_SYS + AT91_DBGU,
+		.end	= AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91_ID_SYS,
+		.end	= AT91_ID_SYS,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data dbgu_data = {
+	.use_dma_tx	= 0,
+	.use_dma_rx	= 0,		/* DBGU not capable of receive DMA */
+	.regs		= (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
+};
+
+static struct platform_device at91sam9263_dbgu_device = {
+	.name		= "atmel_usart",
+	.id		= 0,
+	.dev		= {
+				.platform_data	= &dbgu_data,
+				.coherent_dma_mask = 0xffffffff,
+	},
+	.resource	= dbgu_resources,
+	.num_resources	= ARRAY_SIZE(dbgu_resources),
+};
+
+static inline void configure_dbgu_pins(void)
+{
+	at91_set_A_periph(AT91_PIN_PC30, 0);		/* DRXD */
+	at91_set_A_periph(AT91_PIN_PC31, 1);		/* DTXD */
+}
+
+static struct resource uart0_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_US0,
+		.end	= AT91SAM9263_BASE_US0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_US0,
+		.end	= AT91SAM9263_ID_US0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data uart0_data = {
+	.use_dma_tx	= 1,
+	.use_dma_rx	= 1,
+};
+
+static struct platform_device at91sam9263_uart0_device = {
+	.name		= "atmel_usart",
+	.id		= 1,
+	.dev		= {
+				.platform_data	= &uart0_data,
+				.coherent_dma_mask = 0xffffffff,
+	},
+	.resource	= uart0_resources,
+	.num_resources	= ARRAY_SIZE(uart0_resources),
+};
+
+static inline void configure_usart0_pins(void)
+{
+	at91_set_A_periph(AT91_PIN_PA26, 1);		/* TXD0 */
+	at91_set_A_periph(AT91_PIN_PA27, 0);		/* RXD0 */
+	at91_set_A_periph(AT91_PIN_PA28, 0);		/* RTS0 */
+	at91_set_A_periph(AT91_PIN_PA29, 0);		/* CTS0 */
+}
+
+static struct resource uart1_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_US1,
+		.end	= AT91SAM9263_BASE_US1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_US1,
+		.end	= AT91SAM9263_ID_US1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data uart1_data = {
+	.use_dma_tx	= 1,
+	.use_dma_rx	= 1,
+};
+
+static struct platform_device at91sam9263_uart1_device = {
+	.name		= "atmel_usart",
+	.id		= 2,
+	.dev		= {
+				.platform_data	= &uart1_data,
+				.coherent_dma_mask = 0xffffffff,
+	},
+	.resource	= uart1_resources,
+	.num_resources	= ARRAY_SIZE(uart1_resources),
+};
+
+static inline void configure_usart1_pins(void)
+{
+	at91_set_A_periph(AT91_PIN_PD0, 1);		/* TXD1 */
+	at91_set_A_periph(AT91_PIN_PD1, 0);		/* RXD1 */
+	at91_set_B_periph(AT91_PIN_PD7, 0);		/* RTS1 */
+	at91_set_B_periph(AT91_PIN_PD8, 0);		/* CTS1 */
+}
+
+static struct resource uart2_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_US2,
+		.end	= AT91SAM9263_BASE_US2 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_US2,
+		.end	= AT91SAM9263_ID_US2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data uart2_data = {
+	.use_dma_tx	= 1,
+	.use_dma_rx	= 1,
+};
+
+static struct platform_device at91sam9263_uart2_device = {
+	.name		= "atmel_usart",
+	.id		= 3,
+	.dev		= {
+				.platform_data	= &uart2_data,
+				.coherent_dma_mask = 0xffffffff,
+	},
+	.resource	= uart2_resources,
+	.num_resources	= ARRAY_SIZE(uart2_resources),
+};
+
+static inline void configure_usart2_pins(void)
+{
+	at91_set_A_periph(AT91_PIN_PD2, 1);		/* TXD2 */
+	at91_set_A_periph(AT91_PIN_PD3, 0);		/* RXD2 */
+	at91_set_B_periph(AT91_PIN_PD5, 0);		/* RTS2 */
+	at91_set_B_periph(AT91_PIN_PD6, 0);		/* CTS2 */
+}
+
+struct platform_device *at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
+struct platform_device *atmel_default_console_device;	/* the serial console device */
+
+void __init at91_init_serial(struct at91_uart_config *config)
+{
+	int i;
+
+	/* Fill in list of supported UARTs */
+	for (i = 0; i < config->nr_tty; i++) {
+		switch (config->tty_map[i]) {
+			case 0:
+				configure_usart0_pins();
+				at91_uarts[i] = &at91sam9263_uart0_device;
+				at91_clock_associate("usart0_clk", &at91sam9263_uart0_device.dev, "usart");
+				break;
+			case 1:
+				configure_usart1_pins();
+				at91_uarts[i] = &at91sam9263_uart1_device;
+				at91_clock_associate("usart1_clk", &at91sam9263_uart1_device.dev, "usart");
+				break;
+			case 2:
+				configure_usart2_pins();
+				at91_uarts[i] = &at91sam9263_uart2_device;
+				at91_clock_associate("usart2_clk", &at91sam9263_uart2_device.dev, "usart");
+				break;
+			case 3:
+				configure_dbgu_pins();
+				at91_uarts[i] = &at91sam9263_dbgu_device;
+				at91_clock_associate("mck", &at91sam9263_dbgu_device.dev, "usart");
+				break;
+			default:
+				continue;
+		}
+		at91_uarts[i]->id = i;		/* update ID number to mapped ID */
+	}
+
+	/* Set serial console device */
+	if (config->console_tty < ATMEL_MAX_UART)
+		atmel_default_console_device = at91_uarts[config->console_tty];
+	if (!atmel_default_console_device)
+		printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+
+void __init at91_add_device_serial(void)
+{
+	int i;
+
+	for (i = 0; i < ATMEL_MAX_UART; i++) {
+		if (at91_uarts[i])
+			platform_device_register(at91_uarts[i]);
+	}
+}
+#else
+void __init at91_init_serial(struct at91_uart_config *config) {}
+void __init at91_add_device_serial(void) {}
+#endif
+
+
+/* -------------------------------------------------------------------- */
+/*
+ * These devices are always present and don't need any board-specific
+ * setup.
+ */
+static int __init at91_add_standard_devices(void)
+{
+	return 0;
+}
+
+arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91rm9200/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
similarity index 94%
rename from arch/arm/mach-at91rm9200/at91sam926x_time.c
rename to arch/arm/mach-at91/at91sam926x_time.c
index 99df5f6..a4dded2 100644
--- a/arch/arm/mach-at91rm9200/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/at91sam926x_time.c
+ * linux/arch/arm/mach-at91/at91sam926x_time.c
  *
  * Copyright (C) 2005-2006 M. Amine SAYA, ATMEL Rousset, France
  * Revision	 2005 M. Nicolas Diremdjian, ATMEL Rousset, France
@@ -30,7 +30,6 @@
  * Returns number of microseconds since last timer interrupt.  Note that interrupts
  * will have been disabled by do_gettimeofday()
  *  'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy.
- *  'tick' is usecs per jiffy (linux/timex.h).
  */
 static unsigned long at91sam926x_gettimeoffset(void)
 {
@@ -39,7 +38,7 @@
 
 	elapsed = (PIT_PICNT(t) * LATCH) + PIT_CPIV(t);		/* hardware clock cycles */
 
-	return (unsigned long)(elapsed * 1000000) / LATCH;
+	return (unsigned long)(elapsed * jiffies_to_usecs(1)) / LATCH;
 }
 
 /*
diff --git a/arch/arm/mach-at91rm9200/board-1arm.c b/arch/arm/mach-at91/board-1arm.c
similarity index 97%
rename from arch/arm/mach-at91rm9200/board-1arm.c
rename to arch/arm/mach-at91/board-1arm.c
index 971c3e2..2d3d4b6 100644
--- a/arch/arm/mach-at91rm9200/board-1arm.c
+++ b/arch/arm/mach-at91/board-1arm.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/board-1arm.c
+ * linux/arch/arm/mach-at91/board-1arm.c
  *
  *  Copyright (C) 2005 SAN People
  *
diff --git a/arch/arm/mach-at91rm9200/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c
similarity index 97%
rename from arch/arm/mach-at91rm9200/board-carmeva.c
rename to arch/arm/mach-at91/board-carmeva.c
index 654f037..b451861 100644
--- a/arch/arm/mach-at91rm9200/board-carmeva.c
+++ b/arch/arm/mach-at91/board-carmeva.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/board-carmeva.c
+ * linux/arch/arm/mach-at91/board-carmeva.c
  *
  *  Copyright (c) 2005 Peer Georgi
  *  		       Conitec Datasystems
@@ -134,7 +134,7 @@
 	/* Compact Flash */
 //	at91_add_device_cf(&carmeva_cf_data);
 	/* MMC */
-	at91_add_device_mmc(&carmeva_mmc_data);
+	at91_add_device_mmc(0, &carmeva_mmc_data);
 }
 
 MACHINE_START(CARMEVA, "Carmeva")
diff --git a/arch/arm/mach-at91rm9200/board-csb337.c b/arch/arm/mach-at91/board-csb337.c
similarity index 78%
rename from arch/arm/mach-at91rm9200/board-csb337.c
rename to arch/arm/mach-at91/board-csb337.c
index b8bb805..e18a41e 100644
--- a/arch/arm/mach-at91rm9200/board-csb337.c
+++ b/arch/arm/mach-at91/board-csb337.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/board-csb337.c
+ * linux/arch/arm/mach-at91/board-csb337.c
  *
  *  Copyright (C) 2005 SAN People
  *
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
+#include <linux/mtd/physmap.h>
 
 #include <asm/hardware.h>
 #include <asm/setup.h>
@@ -112,6 +113,42 @@
 	},
 };
 
+#define CSB_FLASH_BASE	AT91_CHIPSELECT_0
+#define CSB_FLASH_SIZE	0x800000
+
+static struct mtd_partition csb_flash_partitions[] = {
+	{
+		.name		= "uMON flash",
+		.offset		= 0,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= MTD_WRITEABLE,	/* read only */
+	}
+};
+
+static struct physmap_flash_data csb_flash_data = {
+	.width		= 2,
+	.parts		= csb_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(csb_flash_partitions),
+};
+
+static struct resource csb_flash_resources[] = {
+	{
+		.start	= CSB_FLASH_BASE,
+		.end	= CSB_FLASH_BASE + CSB_FLASH_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device csb_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+				.platform_data = &csb_flash_data,
+			},
+	.resource	= csb_flash_resources,
+	.num_resources	= ARRAY_SIZE(csb_flash_resources),
+};
+
 static void __init csb337_board_init(void)
 {
 	/* Serial */
@@ -130,7 +167,9 @@
 	/* SPI */
 	at91_add_device_spi(csb337_spi_devices, ARRAY_SIZE(csb337_spi_devices));
 	/* MMC */
-	at91_add_device_mmc(&csb337_mmc_data);
+	at91_add_device_mmc(0, &csb337_mmc_data);
+	/* NOR flash */
+	platform_device_register(&csb_flash);
 }
 
 MACHINE_START(CSB337, "Cogent CSB337")
diff --git a/arch/arm/mach-at91rm9200/board-csb637.c b/arch/arm/mach-at91/board-csb637.c
similarity index 74%
rename from arch/arm/mach-at91rm9200/board-csb637.c
rename to arch/arm/mach-at91/board-csb637.c
index a29fa0e8..77f04b9 100644
--- a/arch/arm/mach-at91rm9200/board-csb637.c
+++ b/arch/arm/mach-at91/board-csb637.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/board-csb637.c
+ * linux/arch/arm/mach-at91/board-csb637.c
  *
  *  Copyright (C) 2005 SAN People
  *
@@ -23,6 +23,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
 
 #include <asm/hardware.h>
 #include <asm/setup.h>
@@ -81,6 +82,42 @@
 	.pullup_pin   = AT91_PIN_PB1,
 };
 
+#define CSB_FLASH_BASE	AT91_CHIPSELECT_0
+#define CSB_FLASH_SIZE	0x1000000
+
+static struct mtd_partition csb_flash_partitions[] = {
+	{
+		.name		= "uMON flash",
+		.offset		= 0,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= MTD_WRITEABLE,	/* read only */
+	}
+};
+
+static struct physmap_flash_data csb_flash_data = {
+	.width		= 2,
+	.parts		= csb_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(csb_flash_partitions),
+};
+
+static struct resource csb_flash_resources[] = {
+	{
+		.start	= CSB_FLASH_BASE,
+		.end	= CSB_FLASH_BASE + CSB_FLASH_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device csb_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+				.platform_data = &csb_flash_data,
+			},
+	.resource	= csb_flash_resources,
+	.num_resources	= ARRAY_SIZE(csb_flash_resources),
+};
+
 static void __init csb637_board_init(void)
 {
 	/* Serial */
@@ -95,6 +132,8 @@
 	at91_add_device_i2c();
 	/* SPI */
 	at91_add_device_spi(NULL, 0);
+	/* NOR flash */
+	platform_device_register(&csb_flash);
 }
 
 MACHINE_START(CSB637, "Cogent CSB637")
diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91/board-dk.c
similarity index 98%
rename from arch/arm/mach-at91rm9200/board-dk.c
rename to arch/arm/mach-at91/board-dk.c
index 7522bf9..6043c38 100644
--- a/arch/arm/mach-at91rm9200/board-dk.c
+++ b/arch/arm/mach-at91/board-dk.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/board-dk.c
+ * linux/arch/arm/mach-at91/board-dk.c
  *
  *  Copyright (C) 2005 SAN People
  *
@@ -194,7 +194,7 @@
 #else
 	/* MMC */
 	at91_set_gpio_output(AT91_PIN_PB7, 1);	/* this MMC card slot can optionally use SPI signaling (CS3). */
-	at91_add_device_mmc(&dk_mmc_data);
+	at91_add_device_mmc(0, &dk_mmc_data);
 #endif
 	/* NAND */
 	at91_add_device_nand(&dk_nand_data);
diff --git a/arch/arm/mach-at91rm9200/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c
similarity index 96%
rename from arch/arm/mach-at91rm9200/board-eb9200.c
rename to arch/arm/mach-at91/board-eb9200.c
index 80b72cf..20458b5 100644
--- a/arch/arm/mach-at91rm9200/board-eb9200.c
+++ b/arch/arm/mach-at91/board-eb9200.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/board-eb9200.c
+ * linux/arch/arm/mach-at91/board-eb9200.c
  *
  *  Copyright (C) 2005 SAN People, adapted for ATEB9200 from Embest
  *  by Andrew Patrikalakis
@@ -109,7 +109,7 @@
 	at91_add_device_spi(NULL, 0);
 	/* MMC */
 	/* only supports 1 or 4 bit interface, not wired through to SPI */
-	at91_add_device_mmc(&eb9200_mmc_data);
+	at91_add_device_mmc(0, &eb9200_mmc_data);
 }
 
 MACHINE_START(ATEB9200, "Embest ATEB9200")
diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91/board-ek.c
similarity index 97%
rename from arch/arm/mach-at91rm9200/board-ek.c
rename to arch/arm/mach-at91/board-ek.c
index c4fdb41..322fdd7 100644
--- a/arch/arm/mach-at91rm9200/board-ek.c
+++ b/arch/arm/mach-at91/board-ek.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/board-ek.c
+ * linux/arch/arm/mach-at91/board-ek.c
  *
  *  Copyright (C) 2005 SAN People
  *
@@ -154,7 +154,7 @@
 #else
 	/* MMC */
 	at91_set_gpio_output(AT91_PIN_PB22, 1);	/* this MMC card slot can optionally use SPI signaling (CS3). */
-	at91_add_device_mmc(&ek_mmc_data);
+	at91_add_device_mmc(0, &ek_mmc_data);
 #endif
 	/* NOR Flash */
 	platform_device_register(&ek_flash);
diff --git a/arch/arm/mach-at91rm9200/board-kafa.c b/arch/arm/mach-at91/board-kafa.c
similarity index 98%
rename from arch/arm/mach-at91rm9200/board-kafa.c
rename to arch/arm/mach-at91/board-kafa.c
index 6ef3c48..c77d84c 100644
--- a/arch/arm/mach-at91rm9200/board-kafa.c
+++ b/arch/arm/mach-at91/board-kafa.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/board-kafa.c
+ * linux/arch/arm/mach-at91/board-kafa.c
  *
  *  Copyright (C) 2006 Sperry-Sun
  *
diff --git a/arch/arm/mach-at91rm9200/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c
similarity index 97%
rename from arch/arm/mach-at91rm9200/board-kb9202.c
rename to arch/arm/mach-at91/board-kb9202.c
index 759d819..76f6e1e 100644
--- a/arch/arm/mach-at91rm9200/board-kb9202.c
+++ b/arch/arm/mach-at91/board-kb9202.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/board-kb9202.c
+ * linux/arch/arm/mach-at91/board-kb9202.c
  *
  *  Copyright (c) 2005 kb_admin
  *  		       KwikByte, Inc.
@@ -122,7 +122,7 @@
 	/* USB Device */
 	at91_add_device_udc(&kb9202_udc_data);
 	/* MMC */
-	at91_add_device_mmc(&kb9202_mmc_data);
+	at91_add_device_mmc(0, &kb9202_mmc_data);
 	/* I2C */
 	at91_add_device_i2c();
 	/* SPI */
diff --git a/arch/arm/mach-at91rm9200/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c
similarity index 96%
rename from arch/arm/mach-at91rm9200/board-sam9260ek.c
rename to arch/arm/mach-at91/board-sam9260ek.c
index da5d58a..57fb449 100644
--- a/arch/arm/mach-at91rm9200/board-sam9260ek.c
+++ b/arch/arm/mach-at91/board-sam9260ek.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/board-ek.c
+ * linux/arch/arm/mach-at91/board-sam9260ek.c
  *
  *  Copyright (C) 2005 SAN People
  *  Copyright (C) 2006 Atmel
@@ -118,7 +118,7 @@
 /*
  * MACB Ethernet device
  */
-static struct __initdata eth_platform_data ek_macb_data = {
+static struct __initdata at91_eth_data ek_macb_data = {
 	.phy_irq_pin	= AT91_PIN_PA7,
 	.is_rmii	= 1,
 };
@@ -187,7 +187,7 @@
 	/* Ethernet */
 	at91_add_device_eth(&ek_macb_data);
 	/* MMC */
-	at91_add_device_mmc(&ek_mmc_data);
+	at91_add_device_mmc(0, &ek_mmc_data);
 }
 
 MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
diff --git a/arch/arm/mach-at91rm9200/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
similarity index 98%
rename from arch/arm/mach-at91rm9200/board-sam9261ek.c
rename to arch/arm/mach-at91/board-sam9261ek.c
index 30b490d..b7e7724 100644
--- a/arch/arm/mach-at91rm9200/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/board-ek.c
+ * linux/arch/arm/mach-at91/board-sam9261ek.c
  *
  *  Copyright (C) 2005 SAN People
  *  Copyright (C) 2006 Atmel
@@ -243,7 +243,7 @@
 	at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
 #else
 	/* MMC */
-	at91_add_device_mmc(&ek_mmc_data);
+	at91_add_device_mmc(0, &ek_mmc_data);
 #endif
 }
 
diff --git a/arch/arm/mach-at91rm9200/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9263ek.c
similarity index 73%
copy from arch/arm/mach-at91rm9200/board-sam9260ek.c
copy to arch/arm/mach-at91/board-sam9263ek.c
index da5d58a..8fdce11 100644
--- a/arch/arm/mach-at91rm9200/board-sam9260ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -1,8 +1,8 @@
 /*
- * linux/arch/arm/mach-at91rm9200/board-ek.c
+ * linux/arch/arm/mach-at91/board-sam9263ek.c
  *
  *  Copyright (C) 2005 SAN People
- *  Copyright (C) 2006 Atmel
+ *  Copyright (C) 2007 Atmel Corporation.
  *
  * 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
@@ -44,19 +44,19 @@
 
 /*
  * Serial port configuration.
- *    0 .. 5 = USART0 .. USART5
- *    6      = DBGU
+ *    0 .. 2 = USART0 .. USART2
+ *    3      = DBGU
  */
 static struct at91_uart_config __initdata ek_uart_config = {
 	.console_tty	= 0,				/* ttyS0 */
-	.nr_tty		= 3,
-	.tty_map	= { 6, 0, 1, -1, -1, -1, -1 }	/* ttyS0, ..., ttyS6 */
+	.nr_tty		= 2,
+	.tty_map	= { 3, 0, -1, -1, }		/* ttyS0, ..., ttyS3 */
 };
 
 static void __init ek_map_io(void)
 {
-	/* Initialize processor: 18.432 MHz crystal */
-	at91sam9260_initialize(18432000);
+	/* Initialize processor: 16.367 MHz crystal */
+	at91sam9263_initialize(16367660);
 
 	/* Setup the serial ports and console */
 	at91_init_serial(&ek_uart_config);
@@ -64,7 +64,7 @@
 
 static void __init ek_init_irq(void)
 {
-	at91sam9260_init_interrupts(NULL);
+	at91sam9263_init_interrupts(NULL);
 }
 
 
@@ -73,13 +73,14 @@
  */
 static struct at91_usbh_data __initdata ek_usbh_data = {
 	.ports		= 2,
+	.vbus_pin	= { AT91_PIN_PA24, AT91_PIN_PA21 },
 };
 
 /*
  * USB Device port
  */
 static struct at91_udc_data __initdata ek_udc_data = {
-	.vbus_pin	= AT91_PIN_PC5,
+	.vbus_pin	= AT91_PIN_PA25,
 	.pullup_pin	= 0,		/* pull-up driven by UDC */
 };
 
@@ -88,13 +89,6 @@
  * SPI devices.
  */
 static struct spi_board_info ek_spi_devices[] = {
-#if !defined(CONFIG_MMC_AT91)
-	{	/* DataFlash chip */
-		.modalias	= "mtd_dataflash",
-		.chip_select	= 1,
-		.max_speed_hz	= 15 * 1000 * 1000,
-		.bus_num	= 0,
-	},
 #if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
 	{	/* DataFlash card */
 		.modalias	= "mtd_dataflash",
@@ -103,24 +97,17 @@
 		.bus_num	= 0,
 	},
 #endif
-#endif
-#if defined(CONFIG_SND_AT73C213)
-	{	/* AT73C213 DAC */
-		.modalias	= "snd_at73c213",
-		.chip_select	= 0,
-		.max_speed_hz	= 10 * 1000 * 1000,
-		.bus_num	= 1,
-	},
-#endif
 };
 
 
 /*
- * MACB Ethernet device
+ * MCI (SD/MMC)
  */
-static struct __initdata eth_platform_data ek_macb_data = {
-	.phy_irq_pin	= AT91_PIN_PA7,
-	.is_rmii	= 1,
+static struct at91_mmc_data __initdata ek_mmc_data = {
+	.wire4		= 1,
+	.det_pin	= AT91_PIN_PE18,
+	.wp_pin		= AT91_PIN_PE19,
+//	.vcc_pin	= ... not connected
 };
 
 
@@ -131,11 +118,11 @@
 	{
 		.name	= "Partition 1",
 		.offset	= 0,
-		.size	= 256 * 1024,
+		.size	= 64 * 1024 * 1024,
 	},
 	{
 		.name	= "Partition 2",
-		.offset	= 256 * 1024,
+		.offset	= 64 * 1024 * 1024,
 		.size	= MTDPART_SIZ_FULL,
 	},
 };
@@ -150,8 +137,8 @@
 	.ale		= 21,
 	.cle		= 22,
 //	.det_pin	= ... not connected
-	.rdy_pin	= AT91_PIN_PC13,
-	.enable_pin	= AT91_PIN_PC14,
+	.rdy_pin	= AT91_PIN_PA22,
+	.enable_pin	= AT91_PIN_PD15,
 	.partition_info	= nand_partitions,
 #if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
 	.bus_width_16	= 1,
@@ -161,17 +148,6 @@
 };
 
 
-/*
- * MCI (SD/MMC)
- */
-static struct at91_mmc_data __initdata ek_mmc_data = {
-	.slot_b		= 1,
-	.wire4		= 1,
-//	.det_pin	= ... not connected
-//	.wp_pin		= ... not connected
-//	.vcc_pin	= ... not connected
-};
-
 static void __init ek_board_init(void)
 {
 	/* Serial */
@@ -182,15 +158,13 @@
 	at91_add_device_udc(&ek_udc_data);
 	/* SPI */
 	at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+	/* MMC */
+	at91_add_device_mmc(1, &ek_mmc_data);
 	/* NAND */
 	at91_add_device_nand(&ek_nand_data);
-	/* Ethernet */
-	at91_add_device_eth(&ek_macb_data);
-	/* MMC */
-	at91_add_device_mmc(&ek_mmc_data);
 }
 
-MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
+MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
 	/* Maintainer: Atmel */
 	.phys_io	= AT91_BASE_SYS,
 	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
diff --git a/arch/arm/mach-at91rm9200/clock.c b/arch/arm/mach-at91/clock.c
similarity index 93%
rename from arch/arm/mach-at91rm9200/clock.c
rename to arch/arm/mach-at91/clock.c
index 36a8e4d..06c9a05 100644
--- a/arch/arm/mach-at91rm9200/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/clock.c
+ * linux/arch/arm/mach-at91/clock.c
  *
  * Copyright (C) 2005 David Brownell
  * Copyright (C) 2005 Ivan Kokshaysky
@@ -525,27 +525,6 @@
 	return 0;
 }
 
-/*
- * Several unused clocks may be active.  Turn them off.
- */
-static void __init at91_periphclk_reset(void)
-{
-	unsigned long reg;
-	struct clk *clk;
-
-	reg = at91_sys_read(AT91_PMC_PCSR);
-
-	list_for_each_entry(clk, &clocks, node) {
-		if (clk->mode != pmc_periph_mode)
-			continue;
-
-		if (clk->users > 0)
-			reg &= ~clk->pmc_mask;
-	}
-
-	at91_sys_write(AT91_PMC_PCDR, reg);
-}
-
 static struct clk *const standard_pmc_clocks[] __initdata = {
 	/* four primary clocks */
 	&clk32k,
@@ -586,7 +565,7 @@
 		pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
 
 	/*
-	 * USB clock init:  choose 48 MHz PLLB value, turn all clocks off,
+	 * USB clock init:  choose 48 MHz PLLB value,
 	 * disable 48MHz clock during usb peripheral suspend.
 	 *
 	 * REVISIT:  assumes MCK doesn't derive from PLLB!
@@ -596,16 +575,10 @@
 	if (cpu_is_at91rm9200()) {
 		uhpck.pmc_mask = AT91RM9200_PMC_UHP;
 		udpck.pmc_mask = AT91RM9200_PMC_UDP;
-		at91_sys_write(AT91_PMC_SCDR, AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP);
 		at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
-	} else if (cpu_is_at91sam9260()) {
+	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) {
 		uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
 		udpck.pmc_mask = AT91SAM926x_PMC_UDP;
-		at91_sys_write(AT91_PMC_SCDR, AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP);
-	} else if (cpu_is_at91sam9261()) {
-		uhpck.pmc_mask = (AT91SAM926x_PMC_UHP | AT91_PMC_HCK0);
-		udpck.pmc_mask = AT91SAM926x_PMC_UDP;
-		at91_sys_write(AT91_PMC_SCDR, AT91SAM926x_PMC_UHP | AT91_PMC_HCK0 | AT91SAM926x_PMC_UDP);
 	}
 	at91_sys_write(AT91_CKGR_PLLBR, 0);
 
@@ -634,11 +607,34 @@
 		(unsigned) main_clock / 1000000,
 		((unsigned) main_clock % 1000000) / 1000);
 
-	/* disable all programmable clocks */
-	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK0 | AT91_PMC_PCK1 | AT91_PMC_PCK2 | AT91_PMC_PCK3);
+	return 0;
+}
 
-	/* disable all other unused peripheral clocks */
-	at91_periphclk_reset();
+/*
+ * Several unused clocks may be active.  Turn them off.
+ */
+static int __init at91_clock_reset(void)
+{
+	unsigned long pcdr = 0;
+	unsigned long scdr = 0;
+	struct clk *clk;
+
+	list_for_each_entry(clk, &clocks, node) {
+		if (clk->users > 0)
+			continue;
+
+		if (clk->mode == pmc_periph_mode)
+			pcdr |= clk->pmc_mask;
+
+		if (clk->mode == pmc_sys_mode)
+			scdr |= clk->pmc_mask;
+
+		pr_debug("Clocks: disable unused %s\n", clk->name);
+	}
+
+	at91_sys_write(AT91_PMC_PCDR, pcdr);
+	at91_sys_write(AT91_PMC_SCDR, scdr);
 
 	return 0;
 }
+late_initcall(at91_clock_reset);
diff --git a/arch/arm/mach-at91rm9200/clock.h b/arch/arm/mach-at91/clock.h
similarity index 94%
rename from arch/arm/mach-at91rm9200/clock.h
rename to arch/arm/mach-at91/clock.h
index b5c7a2e..1ba3b95 100644
--- a/arch/arm/mach-at91rm9200/clock.h
+++ b/arch/arm/mach-at91/clock.h
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/clock.h
+ * linux/arch/arm/mach-at91/clock.h
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-at91rm9200/generic.h b/arch/arm/mach-at91/generic.h
similarity index 90%
rename from arch/arm/mach-at91rm9200/generic.h
rename to arch/arm/mach-at91/generic.h
index 8c4d5a7..bda2622 100644
--- a/arch/arm/mach-at91rm9200/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/generic.h
+ * linux/arch/arm/mach-at91/generic.h
  *
  *  Copyright (C) 2005 David Brownell
  *
@@ -12,11 +12,13 @@
 extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks);
 extern void __init at91sam9260_initialize(unsigned long main_clock);
 extern void __init at91sam9261_initialize(unsigned long main_clock);
+extern void __init at91sam9263_initialize(unsigned long main_clock);
 
  /* Interrupts */
 extern void __init at91rm9200_init_interrupts(unsigned int priority[]);
 extern void __init at91sam9260_init_interrupts(unsigned int priority[]);
 extern void __init at91sam9261_init_interrupts(unsigned int priority[]);
+extern void __init at91sam9263_init_interrupts(unsigned int priority[]);
 extern void __init at91_aic_init(unsigned int priority[]);
 
  /* Timer */
diff --git a/arch/arm/mach-at91rm9200/gpio.c b/arch/arm/mach-at91/gpio.c
similarity index 99%
rename from arch/arm/mach-at91rm9200/gpio.c
rename to arch/arm/mach-at91/gpio.c
index 15eb5b6..7b87f3f 100644
--- a/arch/arm/mach-at91rm9200/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/gpio.c
+ * linux/arch/arm/mach-at91/gpio.c
  *
  * Copyright (C) 2005 HP Labs
  *
diff --git a/arch/arm/mach-at91rm9200/irq.c b/arch/arm/mach-at91/irq.c
similarity index 98%
rename from arch/arm/mach-at91rm9200/irq.c
rename to arch/arm/mach-at91/irq.c
index 2148daaf..78a5cdb 100644
--- a/arch/arm/mach-at91rm9200/irq.c
+++ b/arch/arm/mach-at91/irq.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/irq.c
+ * linux/arch/arm/mach-at91/irq.c
  *
  *  Copyright (C) 2004 SAN People
  *  Copyright (C) 2004 ATMEL
diff --git a/arch/arm/mach-at91rm9200/leds.c b/arch/arm/mach-at91/leds.c
similarity index 93%
rename from arch/arm/mach-at91rm9200/leds.c
rename to arch/arm/mach-at91/leds.c
index 1a33373..0d51449 100644
--- a/arch/arm/mach-at91rm9200/leds.c
+++ b/arch/arm/mach-at91/leds.c
@@ -86,10 +86,6 @@
 	if (!at91_leds_timer || !at91_leds_cpu)
 		return -ENODEV;
 
-	/* Enable PIO to access the LEDs */
-	at91_set_gpio_output(at91_leds_timer, 1);
-	at91_set_gpio_output(at91_leds_cpu, 1);
-
 	leds_event = at91_leds_event;
 
 	leds_event(led_start);
diff --git a/arch/arm/mach-at91rm9200/pm.c b/arch/arm/mach-at91/pm.c
similarity index 97%
rename from arch/arm/mach-at91rm9200/pm.c
rename to arch/arm/mach-at91/pm.c
index 67aa557..b49bfda 100644
--- a/arch/arm/mach-at91rm9200/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -1,5 +1,5 @@
 /*
- * arch/arm/mach-at91rm9200/pm.c
+ * arch/arm/mach-at91/pm.c
  * AT91 Power Management
  *
  * Copyright (C) 2005 David Brownell
@@ -80,6 +80,8 @@
 #warning "Check SAM9260 USB clocks"
 	} else if (cpu_is_at91sam9261()) {
 #warning "Check SAM9261 USB clocks"
+	} else if (cpu_is_at91sam9263()) {
+#warning "Check SAM9263 USB clocks"
 	}
 
 #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig
index af7904b..575a21d 100644
--- a/arch/arm/mach-ep93xx/Kconfig
+++ b/arch/arm/mach-ep93xx/Kconfig
@@ -51,6 +51,31 @@
 	  Say 'Y' here if you want your kernel to support the Glomation
 	  GESBC-9312-sx board.
 
+config MACH_MICRO9
+        bool
+        default n
+
+config MACH_MICRO9H
+       bool "Support Contec Hypercontrol Micro9-H"
+       select MACH_MICRO9
+       help
+         Say 'Y' here if you want your kernel to support the
+         Contec Hypercontrol Micro9-H board.
+
+config MACH_MICRO9M
+       bool "Support Contec Hypercontrol Micro9-M"
+       select MACH_MICRO9
+       help
+         Say 'Y' here if you want your kernel to support the
+         Contec Hypercontrol Micro9-M board.
+
+config MACH_MICRO9L
+       bool "Support Contec Hypercontrol Micro9-L"
+       select MACH_MICRO9
+       help
+         Say 'Y' here if you want your kernel to support the
+         Contec Hypercontrol Micro9-L board.
+
 config MACH_TS72XX
 	bool "Support Technologic Systems TS-72xx SBC"
 	help
diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile
index b06641d..0d3bf93 100644
--- a/arch/arm/mach-ep93xx/Makefile
+++ b/arch/arm/mach-ep93xx/Makefile
@@ -13,4 +13,5 @@
 obj-$(CONFIG_MACH_EDB9315)	+= edb9315.o
 obj-$(CONFIG_MACH_EDB9315A)	+= edb9315a.o
 obj-$(CONFIG_MACH_GESBC9312)	+= gesbc9312.o
+obj-$(CONFIG_MACH_MICRO9)	+= micro9.o
 obj-$(CONFIG_MACH_TS72XX)	+= ts72xx.o
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 08ad782..f174d1a 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <asm/div64.h>
 #include <asm/hardware.h>
@@ -124,7 +125,7 @@
 	return (unsigned long)rate;
 }
 
-void ep93xx_clock_init(void)
+static int __init ep93xx_clock_init(void)
 {
 	u32 value;
 
@@ -153,4 +154,7 @@
 	printk(KERN_INFO "ep93xx: FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
 		clk_f.rate / 1000000, clk_h.rate / 1000000,
 		clk_p.rate / 1000000);
+
+	return 0;
 }
+arch_initcall(ep93xx_clock_init);
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 6b26346..829aed6 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -152,22 +152,30 @@
 /*************************************************************************
  * GPIO handling for EP93xx
  *************************************************************************/
-static unsigned char gpio_int_enable[2];
-static unsigned char gpio_int_type1[2];
-static unsigned char gpio_int_type2[2];
+static unsigned char gpio_int_unmasked[3];
+static unsigned char gpio_int_enabled[3];
+static unsigned char gpio_int_type1[3];
+static unsigned char gpio_int_type2[3];
 
-static void update_gpio_ab_int_params(int port)
+static void update_gpio_int_params(int abf)
 {
-	if (port == 0) {
+	if (abf == 0) {
 		__raw_writeb(0, EP93XX_GPIO_A_INT_ENABLE);
 		__raw_writeb(gpio_int_type2[0], EP93XX_GPIO_A_INT_TYPE2);
 		__raw_writeb(gpio_int_type1[0], EP93XX_GPIO_A_INT_TYPE1);
-		__raw_writeb(gpio_int_enable[0], EP93XX_GPIO_A_INT_ENABLE);
-	} else if (port == 1) {
+		__raw_writeb(gpio_int_unmasked[0] & gpio_int_enabled[0], EP93XX_GPIO_A_INT_ENABLE);
+	} else if (abf == 1) {
 		__raw_writeb(0, EP93XX_GPIO_B_INT_ENABLE);
 		__raw_writeb(gpio_int_type2[1], EP93XX_GPIO_B_INT_TYPE2);
 		__raw_writeb(gpio_int_type1[1], EP93XX_GPIO_B_INT_TYPE1);
-		__raw_writeb(gpio_int_enable[1], EP93XX_GPIO_B_INT_ENABLE);
+		__raw_writeb(gpio_int_unmasked[1] & gpio_int_enabled[1], EP93XX_GPIO_B_INT_ENABLE);
+	} else if (abf == 2) {
+		__raw_writeb(0, EP93XX_GPIO_F_INT_ENABLE);
+		__raw_writeb(gpio_int_type2[2], EP93XX_GPIO_F_INT_TYPE2);
+		__raw_writeb(gpio_int_type1[2], EP93XX_GPIO_F_INT_TYPE1);
+		__raw_writeb(gpio_int_unmasked[2] & gpio_int_enabled[2], EP93XX_GPIO_F_INT_ENABLE);
+	} else {
+		BUG();
 	}
 }
 
@@ -192,8 +200,13 @@
 	local_irq_save(flags);
 	if (direction == GPIO_OUT) {
 		if (line >= 0 && line < 16) {
-			gpio_int_enable[line >> 3] &= ~(1 << (line & 7));
-			update_gpio_ab_int_params(line >> 3);
+			/* Port A/B.  */
+			gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
+			update_gpio_int_params(line >> 3);
+		} else if (line >= 40 && line < 48) {
+			/* Port F.  */
+			gpio_int_unmasked[2] &= ~(1 << (line & 7));
+			update_gpio_int_params(2);
 		}
 
 		v = __raw_readb(data_direction_register);
@@ -244,8 +257,7 @@
 /*************************************************************************
  * EP93xx IRQ handling
  *************************************************************************/
-static void ep93xx_gpio_ab_irq_handler(unsigned int irq,
-		struct irq_desc *desc)
+static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
 	unsigned char status;
 	int i;
@@ -267,37 +279,46 @@
 	}
 }
 
-static void ep93xx_gpio_ab_irq_mask_ack(unsigned int irq)
+static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	int gpio_irq = IRQ_EP93XX_GPIO(16) + (((irq + 1) & 7) ^ 4);
+
+	desc_handle_irq(gpio_irq, irq_desc + gpio_irq);
+}
+
+static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
 {
 	int line = irq - IRQ_EP93XX_GPIO(0);
 	int port = line >> 3;
 
-	gpio_int_enable[port] &= ~(1 << (line & 7));
-	update_gpio_ab_int_params(port);
+	gpio_int_unmasked[port] &= ~(1 << (line & 7));
+	update_gpio_int_params(port);
 
-	if (line >> 3) {
-		__raw_writel(1 << (line & 7), EP93XX_GPIO_B_INT_ACK);
-	} else {
+	if (port == 0) {
 		__raw_writel(1 << (line & 7), EP93XX_GPIO_A_INT_ACK);
+	} else if (port == 1) {
+		__raw_writel(1 << (line & 7), EP93XX_GPIO_B_INT_ACK);
+	} else if (port == 2) {
+		__raw_writel(1 << (line & 7), EP93XX_GPIO_F_INT_ACK);
 	}
 }
 
-static void ep93xx_gpio_ab_irq_mask(unsigned int irq)
+static void ep93xx_gpio_irq_mask(unsigned int irq)
 {
 	int line = irq - IRQ_EP93XX_GPIO(0);
 	int port = line >> 3;
 
-	gpio_int_enable[port] &= ~(1 << (line & 7));
-	update_gpio_ab_int_params(port);
+	gpio_int_unmasked[port] &= ~(1 << (line & 7));
+	update_gpio_int_params(port);
 }
 
-static void ep93xx_gpio_ab_irq_unmask(unsigned int irq)
+static void ep93xx_gpio_irq_unmask(unsigned int irq)
 {
 	int line = irq - IRQ_EP93XX_GPIO(0);
 	int port = line >> 3;
 
-	gpio_int_enable[port] |= 1 << (line & 7);
-	update_gpio_ab_int_params(port);
+	gpio_int_unmasked[port] |= 1 << (line & 7);
+	update_gpio_int_params(port);
 }
 
 
@@ -306,40 +327,51 @@
  * edge (1) triggered, while gpio_int_type2 controls whether it
  * triggers on low/falling (0) or high/rising (1).
  */
-static int ep93xx_gpio_ab_irq_type(unsigned int irq, unsigned int type)
+static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
 {
 	int port;
 	int line;
 
 	line = irq - IRQ_EP93XX_GPIO(0);
-	gpio_line_config(line, GPIO_IN);
+	if (line >= 0 && line < 16) {
+		gpio_line_config(line, GPIO_IN);
+	} else {
+		gpio_line_config(EP93XX_GPIO_LINE_F(line), GPIO_IN);
+	}
 
 	port = line >> 3;
 	line &= 7;
 
 	if (type & IRQT_RISING) {
+		gpio_int_enabled[port] |= 1 << line;
 		gpio_int_type1[port] |= 1 << line;
 		gpio_int_type2[port] |= 1 << line;
 	} else if (type & IRQT_FALLING) {
+		gpio_int_enabled[port] |= 1 << line;
 		gpio_int_type1[port] |= 1 << line;
 		gpio_int_type2[port] &= ~(1 << line);
 	} else if (type & IRQT_HIGH) {
+		gpio_int_enabled[port] |= 1 << line;
 		gpio_int_type1[port] &= ~(1 << line);
 		gpio_int_type2[port] |= 1 << line;
 	} else if (type & IRQT_LOW) {
+		gpio_int_enabled[port] |= 1 << line;
 		gpio_int_type1[port] &= ~(1 << line);
 		gpio_int_type2[port] &= ~(1 << line);
+	} else {
+		gpio_int_enabled[port] &= ~(1 << line);
 	}
-	update_gpio_ab_int_params(port);
+	update_gpio_int_params(port);
 
 	return 0;
 }
 
-static struct irq_chip ep93xx_gpio_ab_irq_chip = {
-	.ack		= ep93xx_gpio_ab_irq_mask_ack,
-	.mask		= ep93xx_gpio_ab_irq_mask,
-	.unmask		= ep93xx_gpio_ab_irq_unmask,
-	.set_type	= ep93xx_gpio_ab_irq_type,
+static struct irq_chip ep93xx_gpio_irq_chip = {
+	.name		= "GPIO",
+	.ack		= ep93xx_gpio_irq_mask_ack,
+	.mask		= ep93xx_gpio_irq_mask,
+	.unmask		= ep93xx_gpio_irq_unmask,
+	.set_type	= ep93xx_gpio_irq_type,
 };
 
 
@@ -350,12 +382,21 @@
 	vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK);
 	vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK);
 
-	for (irq = IRQ_EP93XX_GPIO(0) ; irq <= IRQ_EP93XX_GPIO(15); irq++) {
-		set_irq_chip(irq, &ep93xx_gpio_ab_irq_chip);
+	for (irq = IRQ_EP93XX_GPIO(0); irq <= IRQ_EP93XX_GPIO(23); irq++) {
+		set_irq_chip(irq, &ep93xx_gpio_irq_chip);
 		set_irq_handler(irq, handle_level_irq);
 		set_irq_flags(irq, IRQF_VALID);
 	}
+
 	set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler);
+	set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler);
 }
 
 
@@ -461,8 +502,6 @@
 {
 	unsigned int v;
 
-	ep93xx_clock_init();
-
 	/*
 	 * Disallow access to MaverickCrunch initially.
 	 */
@@ -477,8 +516,4 @@
 
 	platform_device_register(&ep93xx_rtc_device);
 	platform_device_register(&ep93xx_ohci_device);
-
-#ifdef CONFIG_CRUNCH
-	elf_hwcap |= HWCAP_CRUNCH;
-#endif
 }
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
new file mode 100644
index 0000000..f28c129
--- /dev/null
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -0,0 +1,157 @@
+/*
+ *  linux/arch/arm/mach-ep93xx/micro9.c
+ *
+ * Copyright (C) 2006 Contec Steuerungstechnik & Automation GmbH
+ *                   Manfred Gruber <manfred.gruber@contec.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+
+#include <linux/mtd/physmap.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+static struct ep93xx_eth_data micro9_eth_data = {
+       .phy_id                 = 0x1f,
+};
+
+static struct resource micro9_eth_resource[] = {
+       {
+               .start  = EP93XX_ETHERNET_PHYS_BASE,
+               .end    = EP93XX_ETHERNET_PHYS_BASE + 0xffff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_EP93XX_ETHERNET,
+               .end    = IRQ_EP93XX_ETHERNET,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+static struct platform_device micro9_eth_device = {
+       .name           = "ep93xx-eth",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &micro9_eth_data,
+       },
+       .num_resources = ARRAY_SIZE(micro9_eth_resource),
+       .resource       = micro9_eth_resource,
+};
+
+static void __init micro9_eth_init(void)
+{
+       memcpy(micro9_eth_data.dev_addr,
+               (void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
+       platform_device_register(&micro9_eth_device);
+}
+
+static void __init micro9_init(void)
+{
+       micro9_eth_init();
+}
+
+/*
+ * Micro9-H
+ */
+#ifdef CONFIG_MACH_MICRO9H
+static struct physmap_flash_data micro9h_flash_data = {
+       .width          = 4,
+};
+
+static struct resource micro9h_flash_resource = {
+       .start          = 0x10000000,
+       .end            = 0x13ffffff,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device micro9h_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &micro9h_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &micro9h_flash_resource,
+};
+
+static void __init micro9h_init(void)
+{
+       platform_device_register(&micro9h_flash);
+}
+
+static void __init micro9h_init_machine(void)
+{
+       ep93xx_init_devices();
+       micro9_init();
+       micro9h_init();
+}
+
+MACHINE_START(MICRO9, "Contec Hypercontrol Micro9-H")
+       /* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */
+       .phys_io        = EP93XX_APB_PHYS_BASE,
+       .io_pg_offst    = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
+       .boot_params    = 0x00000100,
+       .map_io         = ep93xx_map_io,
+       .init_irq       = ep93xx_init_irq,
+       .timer          = &ep93xx_timer,
+       .init_machine   = micro9h_init_machine,
+MACHINE_END
+#endif
+
+/*
+ * Micro9-M
+ */
+#ifdef CONFIG_MACH_MICRO9M
+static void __init micro9m_init_machine(void)
+{
+       ep93xx_init_devices();
+       micro9_init();
+}
+
+MACHINE_START(MICRO9M, "Contec Hypercontrol Micro9-M")
+       /* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */
+       .phys_io        = EP93XX_APB_PHYS_BASE,
+       .io_pg_offst    = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
+       .boot_params    = 0x00000100,
+       .map_io         = ep93xx_map_io,
+       .init_irq       = ep93xx_init_irq,
+       .timer          = &ep93xx_timer,
+       .init_machine   = micro9m_init_machine,
+MACHINE_END
+#endif
+
+/*
+ * Micro9-L
+ */
+#ifdef CONFIG_MACH_MICRO9L
+static void __init micro9l_init_machine(void)
+{
+       ep93xx_init_devices();
+       micro9_init();
+}
+
+MACHINE_START(MICRO9L, "Contec Hypercontrol Micro9-L")
+       /* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */
+       .phys_io        = EP93XX_APB_PHYS_BASE,
+       .io_pg_offst    = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
+       .boot_params    = 0x00000100,
+       .map_io         = ep93xx_map_io,
+       .init_irq       = ep93xx_init_irq,
+       .timer          = &ep93xx_timer,
+       .init_machine   = micro9l_init_machine,
+MACHINE_END
+#endif
+
diff --git a/arch/arm/mach-iop13xx/irq.c b/arch/arm/mach-iop13xx/irq.c
index dbbc07c..162b932 100644
--- a/arch/arm/mach-iop13xx/irq.c
+++ b/arch/arm/mach-iop13xx/irq.c
@@ -250,11 +250,14 @@
 	.unmask = iop13xx_irq_unmask3,
 };
 
+extern void iop_init_cp6_handler(void);
+
 void __init iop13xx_init_irq(void)
 {
 	unsigned int i;
 
 	u32 cp_flags = iop13xx_cp6_save();
+	iop_init_cp6_handler();
 
 	/* disable all interrupts */
 	write_intctl_0(0);
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
index 3ec1cd5..8b0ac55 100644
--- a/arch/arm/mach-iop32x/irq.c
+++ b/arch/arm/mach-iop32x/irq.c
@@ -60,6 +60,8 @@
 {
 	int i;
 
+	iop_init_cp6_handler();
+
 	intctl_write(0);
 	intstr_write(0);
 	if (machine_is_glantank() ||
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c
index 2499a77..966aa51 100644
--- a/arch/arm/mach-iop32x/n2100.c
+++ b/arch/arm/mach-iop32x/n2100.c
@@ -120,6 +120,20 @@
 	.map_irq	= n2100_pci_map_irq,
 };
 
+/*
+ * Both r8169 chips on the n2100 exhibit PCI parity problems.  Set
+ * the ->broken_parity_status flag for both ports so that the r8169
+ * driver knows it should ignore error interrupts.
+ */
+static void n2100_fixup_r8169(struct pci_dev *dev)
+{
+	if (dev->bus->number == 0 &&
+	    (dev->devfn == PCI_DEVFN(1, 0) ||
+	     dev->devfn == PCI_DEVFN(2, 0)))
+		dev->broken_parity_status = 1;
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REALTEK, PCI_ANY_ID, n2100_fixup_r8169);
+
 static int __init n2100_pci_init(void)
 {
 	if (machine_is_n2100())
diff --git a/arch/arm/mach-iop33x/irq.c b/arch/arm/mach-iop33x/irq.c
index 00b37f3..effbe6b 100644
--- a/arch/arm/mach-iop33x/irq.c
+++ b/arch/arm/mach-iop33x/irq.c
@@ -110,6 +110,8 @@
 {
 	int i;
 
+	iop_init_cp6_handler();
+
 	intctl0_write(0);
 	intctl1_write(0);
 	intstr0_write(0);
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index e316bd9..8a339cd 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -17,7 +17,7 @@
 	  NSLU2 NAS device. For more information on this platform,
 	  see http://www.nslu2-linux.org
 
-config ARCH_AVILA
+config MACH_AVILA
 	bool "Avila"
 	select PCI
 	help
@@ -25,6 +25,14 @@
 	  Avila Network Platform. For more information on this platform,
 	  see <file:Documentation/arm/IXP4xx>.
 
+config MACH_LOFT
+    bool "Loft"
+    depends on MACH_AVILA
+    help
+	  Say 'Y' here if you want your kernel to support the Giant
+	  Shoulder Inc Loft board (a minor variation on the standard
+	  Gateworks Avila Network Platform).
+
 config ARCH_ADI_COYOTE
 	bool "Coyote"
 	select PCI
@@ -86,7 +94,7 @@
 #
 config	ARCH_IXDP4XX
 	bool
-	depends on ARCH_IXDP425 || ARCH_AVILA || MACH_IXDP465
+	depends on ARCH_IXDP425 || MACH_IXDP465
 	default y
 
 #
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index 640315d..746e297 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -6,6 +6,7 @@
 obj-pci-n	:=
 
 obj-pci-$(CONFIG_ARCH_IXDP4XX)		+= ixdp425-pci.o
+obj-pci-$(CONFIG_MACH_AVILA)		+= avila-pci.o
 obj-pci-$(CONFIG_MACH_IXDPG425)		+= ixdpg425-pci.o
 obj-pci-$(CONFIG_ARCH_ADI_COYOTE)	+= coyote-pci.o
 obj-pci-$(CONFIG_MACH_GTWX5715)		+= gtwx5715-pci.o
@@ -15,6 +16,7 @@
 obj-y	+= common.o
 
 obj-$(CONFIG_ARCH_IXDP4XX)	+= ixdp425-setup.o
+obj-$(CONFIG_MACH_AVILA)	+= avila-setup.o
 obj-$(CONFIG_MACH_IXDPG425)	+= coyote-setup.o
 obj-$(CONFIG_ARCH_ADI_COYOTE)	+= coyote-setup.o
 obj-$(CONFIG_MACH_GTWX5715)	+= gtwx5715-setup.o
diff --git a/arch/arm/mach-ixp4xx/avila-pci.c b/arch/arm/mach-ixp4xx/avila-pci.c
new file mode 100644
index 0000000..3f86769
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/avila-pci.c
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/mach-ixp4xx/avila-pci.c
+ *
+ * Gateworks Avila board-level PCI initialization
+ *
+ * Author: Michael-Luke Jones <mlj28@cam.ac.uk>
+ *
+ * Based on ixdp-pci.c
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+
+#include <asm/mach/pci.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+void __init avila_pci_preinit(void)
+{
+	set_irq_type(IRQ_AVILA_PCI_INTA, IRQT_LOW);
+	set_irq_type(IRQ_AVILA_PCI_INTB, IRQT_LOW);
+	set_irq_type(IRQ_AVILA_PCI_INTC, IRQT_LOW);
+	set_irq_type(IRQ_AVILA_PCI_INTD, IRQT_LOW);
+
+	ixp4xx_pci_preinit();
+}
+
+static int __init avila_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	static int pci_irq_table[AVILA_PCI_IRQ_LINES] = {
+		IRQ_AVILA_PCI_INTA,
+		IRQ_AVILA_PCI_INTB,
+		IRQ_AVILA_PCI_INTC,
+		IRQ_AVILA_PCI_INTD
+	};
+
+	int irq = -1;
+
+	if (slot >= 1 &&
+	slot <= (machine_is_loft() ? LOFT_PCI_MAX_DEV : AVILA_PCI_MAX_DEV) &&
+		pin >= 1 && pin <= AVILA_PCI_IRQ_LINES) {
+		irq = pci_irq_table[(slot + pin - 2) % 4];
+	}
+
+	return irq;
+}
+
+struct hw_pci avila_pci __initdata = {
+	.nr_controllers = 1,
+	.preinit	= avila_pci_preinit,
+	.swizzle	= pci_std_swizzle,
+	.setup		= ixp4xx_setup,
+	.scan		= ixp4xx_scan_bus,
+	.map_irq	= avila_map_irq,
+};
+
+int __init avila_pci_init(void)
+{
+	if (machine_is_avila() || machine_is_loft())
+		pci_common_init(&avila_pci);
+	return 0;
+}
+
+subsys_initcall(avila_pci_init);
+
diff --git a/arch/arm/mach-ixp4xx/avila-setup.c b/arch/arm/mach-ixp4xx/avila-setup.c
new file mode 100644
index 0000000..d59b8dc
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
@@ -0,0 +1,192 @@
+/*
+ * arch/arm/mach-ixp4xx/avila-setup.c
+ *
+ * Gateworks Avila board-setup
+ *
+ * Author: Michael-Luke Jones <mlj28@cam.ac.uk>
+ *
+ * Based on ixdp-setup.c
+ * Copyright (C) 2003-2005 MontaVista Software, Inc.
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <linux/slab.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+static struct flash_platform_data avila_flash_data = {
+	.map_name	= "cfi_probe",
+	.width		= 2,
+};
+
+static struct resource avila_flash_resource = {
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device avila_flash = {
+	.name		= "IXP4XX-Flash",
+	.id		= 0,
+	.dev		= {
+		.platform_data = &avila_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &avila_flash_resource,
+};
+
+static struct ixp4xx_i2c_pins avila_i2c_gpio_pins = {
+	.sda_pin	= AVILA_SDA_PIN,
+	.scl_pin	= AVILA_SCL_PIN,
+};
+
+static struct platform_device avila_i2c_controller = {
+	.name		= "IXP4XX-I2C",
+	.id		= 0,
+	.dev		= {
+		.platform_data = &avila_i2c_gpio_pins,
+	},
+	.num_resources	= 0
+};
+
+static struct resource avila_uart_resources[] = {
+	{
+		.start		= IXP4XX_UART1_BASE_PHYS,
+		.end		= IXP4XX_UART1_BASE_PHYS + 0x0fff,
+		.flags		= IORESOURCE_MEM
+	},
+	{
+		.start		= IXP4XX_UART2_BASE_PHYS,
+		.end		= IXP4XX_UART2_BASE_PHYS + 0x0fff,
+		.flags		= IORESOURCE_MEM
+	}
+};
+
+static struct plat_serial8250_port avila_uart_data[] = {
+	{
+		.mapbase	= IXP4XX_UART1_BASE_PHYS,
+		.membase	= (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+		.irq		= IRQ_IXP4XX_UART1,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= IXP4XX_UART_XTAL,
+	},
+	{
+		.mapbase	= IXP4XX_UART2_BASE_PHYS,
+		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+		.irq		= IRQ_IXP4XX_UART2,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= IXP4XX_UART_XTAL,
+	},
+	{ },
+};
+
+static struct platform_device avila_uart = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev.platform_data	= avila_uart_data,
+	.num_resources		= 2,
+	.resource		= avila_uart_resources
+};
+
+static struct resource avila_pata_resources[] = {
+	{
+		.flags	= IORESOURCE_MEM
+	},
+	{
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "intrq",
+		.start	= IRQ_IXP4XX_GPIO12,
+		.end	= IRQ_IXP4XX_GPIO12,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct ixp4xx_pata_data avila_pata_data = {
+	.cs0_bits	= 0xbfff0043,
+	.cs1_bits	= 0xbfff0043,
+};
+
+static struct platform_device avila_pata = {
+	.name			= "pata_ixp4xx_cf",
+	.id			= 0,
+	.dev.platform_data      = &avila_pata_data,
+	.num_resources		= ARRAY_SIZE(avila_pata_resources),
+	.resource		= avila_pata_resources,
+};
+
+static struct platform_device *avila_devices[] __initdata = {
+	&avila_i2c_controller,
+	&avila_flash,
+	&avila_uart
+};
+
+static void __init avila_init(void)
+{
+	ixp4xx_sys_init();
+
+	avila_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+	avila_flash_resource.end =
+		IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
+
+	platform_add_devices(avila_devices, ARRAY_SIZE(avila_devices));
+
+	avila_pata_resources[0].start = IXP4XX_EXP_BUS_BASE(1);
+	avila_pata_resources[0].end = IXP4XX_EXP_BUS_END(1);
+
+	avila_pata_resources[1].start = IXP4XX_EXP_BUS_BASE(2);
+	avila_pata_resources[1].end = IXP4XX_EXP_BUS_END(2);
+
+	avila_pata_data.cs0_cfg = IXP4XX_EXP_CS1;
+	avila_pata_data.cs1_cfg = IXP4XX_EXP_CS2;
+
+	platform_device_register(&avila_pata);
+
+}
+
+MACHINE_START(AVILA, "Gateworks Avila Network Platform")
+	/* Maintainer: Deepak Saxena <dsaxena@plexity.net> */
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= ixp4xx_map_io,
+	.init_irq	= ixp4xx_init_irq,
+	.timer		= &ixp4xx_timer,
+	.boot_params	= 0x0100,
+	.init_machine	= avila_init,
+MACHINE_END
+
+ /*
+  * Loft is functionally equivalent to Avila except that it has a
+  * different number for the maximum PCI devices.  The MACHINE
+  * structure below is identical to Avila except for the comment.
+  */
+#ifdef CONFIG_MACH_LOFT
+MACHINE_START(LOFT, "Giant Shoulder Inc Loft board")
+	/* Maintainer: Tom Billman <kernel@giantshoulderinc.com> */
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= ixp4xx_map_io,
+	.init_irq	= ixp4xx_init_irq,
+	.timer		= &ixp4xx_timer,
+	.boot_params	= 0x0100,
+	.init_machine	= avila_init,
+MACHINE_END
+#endif
+
diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c
index d5156c0..99c1dc8 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-pci.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c
@@ -66,7 +66,7 @@
 int __init ixdp425_pci_init(void)
 {
 	if (machine_is_ixdp425() || machine_is_ixcdp1100() ||
-			machine_is_avila() || machine_is_ixdp465())
+			machine_is_ixdp465())
 		pci_common_init(&ixdp425_pci);
 	return 0;
 }
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index da72383..04b1d56 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -156,23 +156,3 @@
 	.init_machine	= ixdp425_init,
 MACHINE_END
 #endif
-
-/*
- * Avila is functionally equivalent to IXDP425 except that it adds
- * a CF IDE slot hanging off the expansion bus. When we have a 
- * driver for IXP4xx CF IDE with driver model support we'll move
- * Avila to it's own setup file.
- */
-#ifdef CONFIG_ARCH_AVILA
-MACHINE_START(AVILA, "Gateworks Avila Network Platform")
-	/* Maintainer: Deepak Saxena <dsaxena@plexity.net> */
-	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
-	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
-	.map_io		= ixp4xx_map_io,
-	.init_irq	= ixp4xx_init_irq,
-	.timer		= &ixp4xx_timer,
-	.boot_params	= 0x0100,
-	.init_machine	= ixdp425_init,
-MACHINE_END
-#endif
-
diff --git a/arch/arm/mach-ns9xxx/Kconfig b/arch/arm/mach-ns9xxx/Kconfig
new file mode 100644
index 0000000..8175ba9
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/Kconfig
@@ -0,0 +1,21 @@
+if ARCH_NS9XXX
+
+menu "NS9xxx Implementations"
+
+config MACH_CC9P9360DEV
+	bool "Connect Core 9P 9360 on an A9M9750 Devboard"
+	select PROCESSOR_NS9360
+	select BOARD_A9M9750DEV
+	help
+	  Say Y here if you are using the Digi Connect Core 9P 9360
+	  on an A9M9750 Development Board.
+
+config PROCESSOR_NS9360
+	bool
+
+config BOARD_A9M9750DEV
+	bool
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-ns9xxx/Makefile b/arch/arm/mach-ns9xxx/Makefile
new file mode 100644
index 0000000..91e945f
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/Makefile
@@ -0,0 +1,5 @@
+obj-y := irq.o time.o generic.o
+
+obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o
+
+obj-$(CONFIG_BOARD_A9M9750DEV) += board-a9m9750dev.o
diff --git a/arch/arm/mach-ns9xxx/Makefile.boot b/arch/arm/mach-ns9xxx/Makefile.boot
new file mode 100644
index 0000000..75ed64e
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/Makefile.boot
@@ -0,0 +1,2 @@
+zreladdr-y := 0x108000
+params_phys-y := 0x100
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.c b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
new file mode 100644
index 0000000..2528988
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
@@ -0,0 +1,199 @@
+/*
+ * arch/arm/mach-ns9xxx/board-a9m9750dev.c
+ *
+ * Copyright (C) 2006,2007 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/irq.h>
+
+#include <asm/mach/map.h>
+
+#include <asm/arch-ns9xxx/board.h>
+#include <asm/arch-ns9xxx/regs-sys.h>
+#include <asm/arch-ns9xxx/regs-mem.h>
+#include <asm/arch-ns9xxx/regs-bbu.h>
+#include <asm/arch-ns9xxx/regs-board-a9m9750dev.h>
+
+#include "board-a9m9750dev.h"
+
+static struct map_desc board_a9m9750dev_io_desc[] __initdata = {
+	{ /* FPGA on CS0 */
+		.virtual = io_p2v(NS9XXX_CSxSTAT_PHYS(0)),
+		.pfn = __phys_to_pfn(NS9XXX_CSxSTAT_PHYS(0)),
+		.length = NS9XXX_CS0STAT_LENGTH,
+		.type = MT_DEVICE,
+	},
+};
+
+void __init board_a9m9750dev_map_io(void)
+{
+	iotable_init(board_a9m9750dev_io_desc,
+		     ARRAY_SIZE(board_a9m9750dev_io_desc));
+}
+
+static void a9m9750dev_fpga_ack_irq(unsigned int irq)
+{
+	/* nothing */
+}
+
+static void a9m9750dev_fpga_mask_irq(unsigned int irq)
+{
+	FPGA_IER &= ~(1 << (irq - FPGA_IRQ(0)));
+}
+
+static void a9m9750dev_fpga_maskack_irq(unsigned int irq)
+{
+	a9m9750dev_fpga_mask_irq(irq);
+	a9m9750dev_fpga_ack_irq(irq);
+}
+
+static void a9m9750dev_fpga_unmask_irq(unsigned int irq)
+{
+	FPGA_IER |= 1 << (irq - FPGA_IRQ(0));
+}
+
+static struct irq_chip a9m9750dev_fpga_chip = {
+	.ack		= a9m9750dev_fpga_ack_irq,
+	.mask		= a9m9750dev_fpga_mask_irq,
+	.mask_ack	= a9m9750dev_fpga_maskack_irq,
+	.unmask		= a9m9750dev_fpga_unmask_irq,
+};
+
+static void a9m9750dev_fpga_demux_handler(unsigned int irq,
+		struct irq_desc *desc)
+{
+	int stat = FPGA_ISR;
+
+	while (stat != 0) {
+		int irqno = fls(stat) - 1;
+
+		stat &= ~(1 << irqno);
+
+		desc = irq_desc + FPGA_IRQ(irqno);
+
+		desc_handle_irq(irqno, desc);
+	}
+}
+
+void __init board_a9m9750dev_init_irq(void)
+{
+	u32 reg;
+	int i;
+
+	/*
+	 * configure gpio for IRQ_EXT2
+	 * use GPIO 11, because GPIO 32 is used for the LCD
+	 */
+	/* XXX: proper GPIO handling */
+	BBU_GC(2) &= ~0x2000;
+
+	for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) {
+		set_irq_chip(i, &a9m9750dev_fpga_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+
+	/* IRQ_EXT2: level sensitive + active low */
+	reg = SYS_EIC(2);
+	REGSET(reg, SYS_EIC, PLTY, AL);
+	REGSET(reg, SYS_EIC, LVEDG, LEVEL);
+	SYS_EIC(2) = reg;
+
+	set_irq_chained_handler(IRQ_EXT2,
+			a9m9750dev_fpga_demux_handler);
+}
+
+static struct plat_serial8250_port board_a9m9750dev_serial8250_port[] = {
+	{
+		.iobase         = FPGA_UARTA_BASE,
+		.membase        = (unsigned char*)FPGA_UARTA_BASE,
+		.mapbase        = FPGA_UARTA_BASE,
+		.irq            = IRQ_FPGA_UARTA,
+		.iotype         = UPIO_MEM,
+		.uartclk        = 18432000,
+		.regshift       = 0,
+		.flags          = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
+	}, {
+		.iobase         = FPGA_UARTB_BASE,
+		.membase        = (unsigned char*)FPGA_UARTB_BASE,
+		.mapbase        = FPGA_UARTB_BASE,
+		.irq            = IRQ_FPGA_UARTB,
+		.iotype         = UPIO_MEM,
+		.uartclk        = 18432000,
+		.regshift       = 0,
+		.flags          = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
+	}, {
+		.iobase         = FPGA_UARTC_BASE,
+		.membase        = (unsigned char*)FPGA_UARTC_BASE,
+		.mapbase        = FPGA_UARTC_BASE,
+		.irq            = IRQ_FPGA_UARTC,
+		.iotype         = UPIO_MEM,
+		.uartclk        = 18432000,
+		.regshift       = 0,
+		.flags          = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
+	}, {
+		.iobase         = FPGA_UARTD_BASE,
+		.membase        = (unsigned char*)FPGA_UARTD_BASE,
+		.mapbase        = FPGA_UARTD_BASE,
+		.irq            = IRQ_FPGA_UARTD,
+		.iotype         = UPIO_MEM,
+		.uartclk        = 18432000,
+		.regshift       = 0,
+		.flags          = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
+	}, {
+		/* end marker */
+	},
+};
+
+static struct platform_device board_a9m9750dev_serial_device = {
+	.name = "serial8250",
+	.dev = {
+		.platform_data = board_a9m9750dev_serial8250_port,
+	},
+};
+
+static struct platform_device *board_a9m9750dev_devices[] __initdata = {
+	&board_a9m9750dev_serial_device,
+};
+
+void __init board_a9m9750dev_init_machine(void)
+{
+	u32 reg;
+
+	/* setup static CS0: memory base ... */
+	REGSETIM(SYS_SMCSSMB(0), SYS_SMCSSMB, CSxB,
+			NS9XXX_CSxSTAT_PHYS(0) >> 12);
+
+	/* ... and mask */
+	reg = SYS_SMCSSMM(0);
+	REGSETIM(reg, SYS_SMCSSMM, CSxM, 0xfffff);
+	REGSET(reg, SYS_SMCSSMM, CSEx, EN);
+	SYS_SMCSSMM(0) = reg;
+
+	/* setup static CS0: memory configuration */
+	reg = MEM_SMC(0);
+	REGSET(reg, MEM_SMC, WSMC, OFF);
+	REGSET(reg, MEM_SMC, BSMC, OFF);
+	REGSET(reg, MEM_SMC, EW, OFF);
+	REGSET(reg, MEM_SMC, PB, 1);
+	REGSET(reg, MEM_SMC, PC, AL);
+	REGSET(reg, MEM_SMC, PM, DIS);
+	REGSET(reg, MEM_SMC, MW, 8);
+	MEM_SMC(0) = reg;
+
+	/* setup static CS0: timing */
+	MEM_SMWED(0) = 0x2;
+	MEM_SMOED(0) = 0x2;
+	MEM_SMRD(0) = 0x6;
+	MEM_SMWD(0) = 0x6;
+
+	platform_add_devices(board_a9m9750dev_devices,
+			ARRAY_SIZE(board_a9m9750dev_devices));
+}
+
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.h b/arch/arm/mach-ns9xxx/board-a9m9750dev.h
new file mode 100644
index 0000000..edc75ab
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.h
@@ -0,0 +1,15 @@
+/*
+ * arch/arm/mach-ns9xxx/board-a9m9750dev.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/init.h>
+
+void __init board_a9m9750dev_map_io(void);
+void __init board_a9m9750dev_init_machine(void);
+void __init board_a9m9750dev_init_irq(void);
diff --git a/arch/arm/mach-ns9xxx/generic.c b/arch/arm/mach-ns9xxx/generic.c
new file mode 100644
index 0000000..83e2b65
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/generic.c
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-ns9xxx/generic.c
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/memory.h>
+#include <asm/page.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+#include <asm/arch-ns9xxx/regs-sys.h>
+#include <asm/arch-ns9xxx/regs-mem.h>
+#include <asm/arch-ns9xxx/board.h>
+
+static struct map_desc standard_io_desc[] __initdata = {
+	{ /* BBus */
+		.virtual = io_p2v(0x90000000),
+		.pfn = __phys_to_pfn(0x90000000),
+		.length = 0x00700000,
+		.type = MT_DEVICE,
+	}, { /* AHB */
+		.virtual = io_p2v(0xa0100000),
+		.pfn = __phys_to_pfn(0xa0100000),
+		.length = 0x00900000,
+		.type = MT_DEVICE,
+	},
+};
+
+void __init ns9xxx_map_io(void)
+{
+	iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+}
+
+void __init ns9xxx_init_machine(void)
+{
+}
diff --git a/arch/arm/mach-ns9xxx/generic.h b/arch/arm/mach-ns9xxx/generic.h
new file mode 100644
index 0000000..687e2917
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/generic.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-ns9xxx/generic.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/time.h>
+#include <asm/mach/time.h>
+#include <linux/init.h>
+
+void __init ns9xxx_init_irq(void);
+void __init ns9xxx_map_io(void);
+void __init ns9xxx_init_machine(void);
+
+extern struct sys_timer ns9xxx_timer;
diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c
new file mode 100644
index 0000000..83d9272
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/irq.c
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/mach-ns9xxx/irq.c
+ *
+ * Copyright (C) 2006,2007 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/interrupt.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+#include <asm/arch-ns9xxx/regs-sys.h>
+#include <asm/arch-ns9xxx/irqs.h>
+#include <asm/arch-ns9xxx/board.h>
+
+#include "generic.h"
+
+static void ns9xxx_ack_irq_timer(unsigned int irq)
+{
+	u32 tc = SYS_TC(irq - IRQ_TIMER0);
+
+	REGSET(tc, SYS_TCx, INTC, SET);
+	SYS_TC(irq - IRQ_TIMER0) = tc;
+
+	REGSET(tc, SYS_TCx, INTC, UNSET);
+	SYS_TC(irq - IRQ_TIMER0) = tc;
+}
+
+void (*ns9xxx_ack_irq_functions[NR_IRQS])(unsigned int) = {
+	[IRQ_TIMER0] = ns9xxx_ack_irq_timer,
+	[IRQ_TIMER1] = ns9xxx_ack_irq_timer,
+	[IRQ_TIMER2] = ns9xxx_ack_irq_timer,
+	[IRQ_TIMER3] = ns9xxx_ack_irq_timer,
+};
+
+static void ns9xxx_mask_irq(unsigned int irq)
+{
+	/* XXX: better use cpp symbols */
+	SYS_IC(irq / 4) &= ~(1 << (7 + 8 * (3 - (irq & 3))));
+}
+
+static void ns9xxx_ack_irq(unsigned int irq)
+{
+	if (!ns9xxx_ack_irq_functions[irq]) {
+		printk(KERN_ERR "no ack function for irq %u\n", irq);
+		BUG();
+	}
+
+	ns9xxx_ack_irq_functions[irq](irq);
+	SYS_ISRADDR = 0;
+}
+
+static void ns9xxx_maskack_irq(unsigned int irq)
+{
+	ns9xxx_mask_irq(irq);
+	ns9xxx_ack_irq(irq);
+}
+
+static void ns9xxx_unmask_irq(unsigned int irq)
+{
+	/* XXX: better use cpp symbols */
+	SYS_IC(irq / 4) |= 1 << (7 + 8 * (3 - (irq & 3)));
+}
+
+static struct irq_chip ns9xxx_chip = {
+	.ack		= ns9xxx_ack_irq,
+	.mask		= ns9xxx_mask_irq,
+	.mask_ack	= ns9xxx_maskack_irq,
+	.unmask		= ns9xxx_unmask_irq,
+};
+
+void __init ns9xxx_init_irq(void)
+{
+	int i;
+
+	/* disable all IRQs */
+	for (i = 0; i < 8; ++i)
+		SYS_IC(i) = (4 * i) << 24 | (4 * i + 1) << 16 |
+			(4 * i + 2) << 8 | (4 * i + 3);
+
+	/* simple interrupt prio table:
+	 * prio(x) < prio(y) <=> x < y
+	 */
+	for (i = 0; i < 32; ++i)
+		SYS_IVA(i) = i;
+
+	for (i = IRQ_WATCHDOG; i <= IRQ_EXT3; ++i) {
+		set_irq_chip(i, &ns9xxx_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+}
diff --git a/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c b/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
new file mode 100644
index 0000000..a193dd9
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include "board-a9m9750dev.h"
+#include "generic.h"
+
+static void __init mach_cc9p9360dev_map_io(void)
+{
+	ns9xxx_map_io();
+	board_a9m9750dev_map_io();
+}
+
+static void __init mach_cc9p9360dev_init_irq(void)
+{
+	ns9xxx_init_irq();
+	board_a9m9750dev_init_irq();
+}
+
+static void __init mach_cc9p9360dev_init_machine(void)
+{
+	ns9xxx_init_machine();
+	board_a9m9750dev_init_machine();
+}
+
+MACHINE_START(CC9P9360DEV, "Connect Core 9P 9360 on an A9M9750 Devboard")
+	.map_io = mach_cc9p9360dev_map_io,
+	.init_irq = mach_cc9p9360dev_init_irq,
+	.init_machine = mach_cc9p9360dev_init_machine,
+	.timer = &ns9xxx_timer,
+	.boot_params = 0x100,
+MACHINE_END
diff --git a/arch/arm/mach-ns9xxx/time.c b/arch/arm/mach-ns9xxx/time.c
new file mode 100644
index 0000000..eec05f1
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/time.c
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/mach-ns9xxx/time.c
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/jiffies.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/arch-ns9xxx/regs-sys.h>
+#include <asm/arch-ns9xxx/clock.h>
+#include <asm/arch-ns9xxx/irqs.h>
+#include <asm/arch/system.h>
+#include "generic.h"
+
+#define TIMERCLOCKSELECT 64
+
+static u32 usecs_per_tick;
+
+static irqreturn_t
+ns9xxx_timer_interrupt(int irq, void *dev_id)
+{
+	write_seqlock(&xtime_lock);
+	timer_tick();
+	write_sequnlock(&xtime_lock);
+
+	return IRQ_HANDLED;
+}
+
+static unsigned long ns9xxx_timer_gettimeoffset(void)
+{
+	/* return the microseconds which have passed since the last interrupt
+	 * was _serviced_.  That is, if an interrupt is pending or the counter
+	 * reloads, return one periode more. */
+
+	u32 counter1 = SYS_TR(0);
+	int pending = SYS_ISR & (1 << IRQ_TIMER0);
+	u32 counter2 = SYS_TR(0);
+	u32 elapsed;
+
+	if (pending || counter2 > counter1)
+		elapsed = 2 * SYS_TRC(0) - counter2;
+	else
+		elapsed = SYS_TRC(0) - counter1;
+
+	return (elapsed * usecs_per_tick) >> 16;
+
+}
+
+static struct irqaction ns9xxx_timer_irq = {
+	.name = "NS9xxx Timer Tick",
+	.flags = IRQF_DISABLED | IRQF_TIMER,
+	.handler = ns9xxx_timer_interrupt,
+};
+
+static void __init ns9xxx_timer_init(void)
+{
+	int tc;
+
+	usecs_per_tick =
+		SH_DIV(1000000 * TIMERCLOCKSELECT, ns9xxx_cpuclock(), 16);
+
+	/* disable timer */
+	if ((tc = SYS_TC(0)) & SYS_TCx_TEN)
+		SYS_TC(0) = tc & ~SYS_TCx_TEN;
+
+	SYS_TRC(0) = SH_DIV(ns9xxx_cpuclock(), (TIMERCLOCKSELECT * HZ), 0);
+
+	REGSET(tc, SYS_TCx, TEN, EN);
+	REGSET(tc, SYS_TCx, TLCS, DIV64); /* This must match TIMERCLOCKSELECT */
+	REGSET(tc, SYS_TCx, INTS, EN);
+	REGSET(tc, SYS_TCx, UDS, DOWN);
+	REGSET(tc, SYS_TCx, TDBG, STOP);
+	REGSET(tc, SYS_TCx, TSZ, 32);
+	REGSET(tc, SYS_TCx, REN, EN);
+	SYS_TC(0) = tc;
+
+	setup_irq(IRQ_TIMER0, &ns9xxx_timer_irq);
+}
+
+struct sys_timer ns9xxx_timer = {
+	.init = ns9xxx_timer_init,
+	.offset = ns9xxx_timer_gettimeoffset,
+};
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 9de1278..390524c 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -338,6 +338,27 @@
 	.num_resources	= ARRAY_SIZE(i2c_resources),
 };
 
+#ifdef CONFIG_PXA27x
+static struct resource i2c_power_resources[] = {
+	{
+		.start	= 0x40f00180,
+		.end	= 0x40f001a3,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_PWRI2C,
+		.end	= IRQ_PWRI2C,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device i2c_power_device = {
+	.name		= "pxa2xx-i2c",
+	.id		= 1,
+	.resource	= i2c_power_resources,
+	.num_resources	= ARRAY_SIZE(i2c_resources),
+};
+#endif
+
 void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
 {
 	i2c_device.dev.platform_data = info;
@@ -392,6 +413,9 @@
 	&stuart_device,
 	&pxaficp_device,
 	&i2c_device,
+#ifdef CONFIG_PXA27x
+	&i2c_power_device,
+#endif
 	&i2s_device,
 	&pxartc_device,
 };
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index 17f5f44..35156ca 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -10,10 +10,21 @@
 config REALVIEW_MPCORE
 	bool "Support MPcore tile"
 	depends on MACH_REALVIEW_EB
+	select CACHE_L2X0
 	help
 	  Enable support for the MPCore tile on the Realview platform.
 	  Since there are device address and interrupt differences, a
 	  kernel built with this option enabled is not compatible with
 	  other tiles.
 
+config REALVIEW_MPCORE_REVB
+	bool "Support MPcore RevB tile"
+	depends on REALVIEW_MPCORE
+	default n
+	help
+	  Enable support for the MPCore RevB tile on the Realview platform.
+	  Since there are device address differences, a
+	  kernel built with this option enabled is not compatible with
+	  other tiles.
+
 endmenu
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index b8484e1..fce3596 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -52,13 +52,14 @@
 	 * core (e.g. timer irq), then they will not have been enabled
 	 * for us: do so
 	 */
-	gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
+	gic_cpu_init(0, __io_address(REALVIEW_GIC_CPU_BASE));
 
 	/*
 	 * let the primary processor know we're out of the
 	 * pen, then head off into the C entry point
 	 */
 	pen_release = -1;
+	smp_wmb();
 
 	/*
 	 * Synchronise with the boot thread.
@@ -102,6 +103,7 @@
 
 	timeout = jiffies + (1 * HZ);
 	while (time_before(jiffies, timeout)) {
+		smp_rmb();
 		if (pen_release == -1)
 			break;
 
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 9741b4d..3dba666 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -31,6 +31,7 @@
 #include <asm/mach-types.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/icst307.h>
+#include <asm/hardware/cache-l2x0.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -57,7 +58,26 @@
 		.pfn		= __phys_to_pfn(REALVIEW_GIC_DIST_BASE),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE,
+	},
+#ifdef CONFIG_REALVIEW_MPCORE
+	{
+		.virtual	= IO_ADDRESS(REALVIEW_GIC1_CPU_BASE),
+		.pfn		= __phys_to_pfn(REALVIEW_GIC1_CPU_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
 	}, {
+		.virtual	= IO_ADDRESS(REALVIEW_GIC1_DIST_BASE),
+		.pfn		= __phys_to_pfn(REALVIEW_GIC1_DIST_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= IO_ADDRESS(REALVIEW_MPCORE_L220_BASE),
+		.pfn		= __phys_to_pfn(REALVIEW_MPCORE_L220_BASE),
+		.length		= SZ_8K,
+		.type		= MT_DEVICE,
+	},
+#endif
+	{
 		.virtual	= IO_ADDRESS(REALVIEW_SCTL_BASE),
 		.pfn		= __phys_to_pfn(REALVIEW_SCTL_BASE),
 		.length		= SZ_4K,
@@ -138,19 +158,29 @@
 #ifdef CONFIG_REALVIEW_MPCORE
 	unsigned int pldctrl;
 	writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK));
-	pldctrl = readl(__io_address(REALVIEW_SYS_BASE)	+ 0xd8);
+	pldctrl = readl(__io_address(REALVIEW_SYS_BASE)	+ REALVIEW_MPCORE_SYS_PLD_CTRL1);
 	pldctrl |= 0x00800000;	/* New irq mode */
-	writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + 0xd8);
+	writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + REALVIEW_MPCORE_SYS_PLD_CTRL1);
 	writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
 #endif
-	gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE));
-	gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
+	gic_dist_init(0, __io_address(REALVIEW_GIC_DIST_BASE), 29);
+	gic_cpu_init(0, __io_address(REALVIEW_GIC_CPU_BASE));
+#ifdef CONFIG_REALVIEW_MPCORE
+	gic_dist_init(1, __io_address(REALVIEW_GIC1_DIST_BASE), 64);
+	gic_cpu_init(1, __io_address(REALVIEW_GIC1_CPU_BASE));
+	gic_cascade_irq(1, IRQ_EB_IRQ1);
+#endif
 }
 
 static void __init realview_eb_init(void)
 {
 	int i;
 
+#ifdef CONFIG_REALVIEW_MPCORE
+	/* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
+	 * Bits:  .... ...0 0111 1001 0000 .... .... .... */
+	l2x0_init(__io_address(REALVIEW_MPCORE_L220_BASE), 0x00790000, 0xfe000fff);
+#endif
 	clk_register(&realview_clcd_clk);
 
 	platform_device_register(&realview_flash_device);
diff --git a/arch/arm/mach-s3c2400/Kconfig b/arch/arm/mach-s3c2400/Kconfig
new file mode 100644
index 0000000..deab072
--- /dev/null
+++ b/arch/arm/mach-s3c2400/Kconfig
@@ -0,0 +1,13 @@
+# arch/arm/mach-s3c2400/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+
+
+menu "S3C2400 Machines"
+
+
+endmenu
+
diff --git a/arch/arm/mach-s3c2400/Makefile b/arch/arm/mach-s3c2400/Makefile
new file mode 100644
index 0000000..7e23f4e
--- /dev/null
+++ b/arch/arm/mach-s3c2400/Makefile
@@ -0,0 +1,15 @@
+# arch/arm/mach-s3c2400/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:=
+obj-				:=
+
+obj-$(CONFIG_CPU_S3C2400)	+= gpio.o
+
+# Machine support
+
diff --git a/arch/arm/mach-s3c2410/s3c2400-gpio.c b/arch/arm/mach-s3c2400/gpio.c
similarity index 95%
rename from arch/arm/mach-s3c2410/s3c2400-gpio.c
rename to arch/arm/mach-s3c2400/gpio.c
index 1576d01..758e160 100644
--- a/arch/arm/mach-s3c2410/s3c2400-gpio.c
+++ b/arch/arm/mach-s3c2400/gpio.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2400-gpio.c
+/* linux/arch/arm/mach-s3c2400/gpio.c
  *
  * Copyright (c) 2006 Lucas Correia Villa Real <lucasvr@gobolinux.org>
  *
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index eb4ec41..d4b013b 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -1,30 +1,69 @@
-if ARCH_S3C2410
+# arch/arm/mach-s3c2410/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
 
-menu "S3C24XX Implementations"
+config CPU_S3C2410
+	bool
+	depends on ARCH_S3C2410
+	select S3C2410_CLOCK
+	select S3C2410_GPIO
+	select S3C2410_PM if PM
+	help
+	  Support for S3C2410 and S3C2410A family from the S3C24XX line
+	  of Samsung Mobile CPUs.
 
-config MACH_AML_M5900
-	bool "AML M5900 Series"
+config CPU_S3C2410_DMA
+	bool
+	depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
+	default y if CPU_S3C2410 || CPU_S3C2442
+	help
+	  DMA device selection for S3C2410 and compatible CPUs
+
+config S3C2410_PM
+	bool
+	help
+	  Power Management code common to S3C2410 and better
+
+config S3C2410_GPIO
+	bool
+	help
+	  GPIO code for S3C2410 and similar processors
+
+config S3C2410_CLOCK
+	bool
+	help
+	  Clock code for the S3C2410, and similar processors
+
+
+menu "S3C2410 Machines"
+
+config ARCH_SMDK2410
+	bool "SMDK2410/A9M2410"
 	select CPU_S3C2410
-	select PM_SIMTEC if PM
+	select MACH_SMDK
 	help
-	   Say Y here if you are using the American Microsystems M5900 Series
-           <http://www.amltd.com>
+	   Say Y here if you are using the SMDK2410 or the derived module A9M2410
+           <http://www.fsforth.de>
 
-config MACH_ANUBIS
-	bool "Simtec Electronics ANUBIS"
-	select CPU_S3C2440
-	select PM_SIMTEC if PM
+config ARCH_H1940
+	bool "IPAQ H1940"
+	select CPU_S3C2410
+	select PM_H1940 if PM
 	help
-	  Say Y here if you are using the Simtec Electronics ANUBIS
-	  development system
+	  Say Y here if you are using the HP IPAQ H1940
 
-config MACH_OSIRIS
-	bool "Simtec IM2440D20 (OSIRIS) module"
-	select CPU_S3C2440
-	select PM_SIMTEC if PM
+config PM_H1940
+	bool
 	help
-	  Say Y here if you are using the Simtec IM2440D20 module, also
-	  known as the Osiris.
+	  Internal node for H1940 and related PM
+
+config MACH_N30
+	bool "Acer N30"
+	select CPU_S3C2410
+	help
+	  Say Y here if you are using the Acer N30
 
 config ARCH_BAST
 	bool "Simtec Electronics BAST (EB2410ITX)"
@@ -35,7 +74,19 @@
 	  Say Y here if you are using the Simtec Electronics EB2410ITX
 	  development board (also known as BAST)
 
-	  Product page: <http://www.simtec.co.uk/products/EB2410ITX/>.
+config MACH_OTOM
+ 	bool "NexVision OTOM Board"
+ 	select CPU_S3C2410
+	help
+ 	  Say Y here if you are using the Nex Vision OTOM board
+
+config MACH_AML_M5900
+	bool "AML M5900 Series"
+	select CPU_S3C2410
+	select PM_SIMTEC if PM
+	help
+	   Say Y here if you are using the American Microsystems M5900 Series
+           <http://www.amltd.com>
 
 config BAST_PC104_IRQ
 	bool "BAST PC104 IRQ support"
@@ -45,74 +96,6 @@
 	  Say Y	here to enable the PC104 IRQ routing on the
 	  Simtec BAST (EB2410ITX)
 
-config PM_H1940
-	bool
-	help
-	  Internal node for H1940 and related PM
-
-config ARCH_H1940
-	bool "IPAQ H1940"
-	select CPU_S3C2410
-	select PM_H1940 if PM
-	help
-	  Say Y here if you are using the HP IPAQ H1940
-
-	  <http://www.handhelds.org/projects/h1940.html>.
-
-config MACH_N30
-	bool "Acer N30"
-	select CPU_S3C2410
-	help
-	  Say Y here if you are using the Acer N30
-
-	  <http://zoo.weinigel.se/n30>.
-
-config MACH_SMDK
-	bool
-	help
-	  Common machine code for SMDK2410 and SMDK2440
-
-config ARCH_SMDK2410
-	bool "SMDK2410/A9M2410"
-	select CPU_S3C2410
-	select MACH_SMDK
-	help
-	   Say Y here if you are using the SMDK2410 or the derived module A9M2410
-           <http://www.fsforth.de>
-
-config ARCH_S3C2440
-	bool "SMDK2440"
-	select CPU_S3C2440
-	select MACH_SMDK
-	help
-	  Say Y here if you are using the SMDK2440.
-
-config SMDK2440_CPU2440
-	bool "SMDK2440 with S3C2440 CPU module"
-	depends on ARCH_S3C2440
-	default y if ARCH_S3C2440
-	select CPU_S3C2440
-
-config SMDK2440_CPU2442
-	bool "SMDM2440 with S3C2442 CPU module"
-	depends on ARCH_S3C2440
-	select CPU_S3C2442
-
-config MACH_S3C2413
-	bool
-	help
-	  Internal node for S3C2413 version of SMDK2413, so that
-	  machine_is_s3c2413() will work when MACH_SMDK2413 is
-	  selected
-
-config MACH_SMDK2413
-	bool "SMDK2413"
-	select CPU_S3C2412
-	select MACH_S3C2413
-	select MACH_SMDK
-	help
-	  Say Y here if you are using an SMDK2413
-
 config MACH_VR1000
 	bool "Thorcom VR1000"
 	select PM_SIMTEC if PM
@@ -120,202 +103,11 @@
 	help
 	  Say Y here if you are using the Thorcom VR1000 board.
 
-	  This linux port is currently being maintained by Simtec, on behalf
-	  of Thorcom. Any queries, please contact Thorcom first.
-
-config MACH_RX3715
-	bool "HP iPAQ rx3715"
-	select CPU_S3C2440
-	select PM_H1940 if PM
+config MACH_QT2410
+	bool "QT2410"
+	select CPU_S3C2410
 	help
-	  Say Y here if you are using the HP iPAQ rx3715.
-
-	  See <http://www.handhelds.org/projects/rx3715.html> for more
-	  information on this project
-
-config MACH_OTOM
- 	bool "NexVision OTOM Board"
- 	select CPU_S3C2410
-	help
- 	  Say Y here if you are using the Nex Vision OTOM board
-
-config MACH_NEXCODER_2440
- 	bool "NexVision NEXCODER 2440 Light Board"
- 	select CPU_S3C2440
-	help
- 	  Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
-
-config MACH_VSTMS
-	bool "VMSTMS"
-	select CPU_S3C2412
-	help
-	  Say Y here if you are using an VSTMS board
+	   Say Y here if you are using the Armzone QT2410
 
 endmenu
 
-config S3C2410_CLOCK
-	bool
-	help
-	  Clock code for the S3C2410, and similar processors
-
-config S3C2410_PM
-	bool
-	help
-	  Power Management code common to S3C2410 and better
-
-config CPU_S3C2410_DMA
-	bool
-	depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
-	default y if CPU_S3C2410 || CPU_S3C2442
-	help
-	  DMA device selection for S3C2410 and compatible CPUs
-
-config CPU_S3C2410
-	bool
-	depends on ARCH_S3C2410
-	select S3C2410_CLOCK
-	select S3C2410_PM if PM
-	help
-	  Support for S3C2410 and S3C2410A family from the S3C24XX line
-	  of Samsung Mobile CPUs.
-
-# internal node to signify if we are only dealing with an S3C2412
-
-config CPU_S3C2412_ONLY
-	bool
-	depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
-		   !CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412
-	default y if CPU_S3C2412
-
-config S3C2412_PM
-	bool
-	help
-	  Internal config node to apply S3C2412 power management
-
-config CPU_S3C2412
-	bool
-	depends on ARCH_S3C2410
-	select S3C2412_PM if PM
-	help
-	  Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
-
-config CPU_S3C244X
-	bool
-	depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
-	help
-	  Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
-
-config CPU_S3C2440
-	bool
-	depends on ARCH_S3C2410
-	select S3C2410_CLOCK
-	select S3C2410_PM if PM
-	select CPU_S3C244X
-	help
-	  Support for S3C2440 Samsung Mobile CPU based systems.
-
-config CPU_S3C2442
-	bool
-	depends on ARCH_S3C2420
-	select S3C2410_CLOCK
-	select S3C2410_PM if PM
-	select CPU_S3C244X
-	help
-	  Support for S3C2442 Samsung Mobile CPU based systems.
-
-comment "S3C2410 Boot"
-
-config S3C2410_BOOT_WATCHDOG
-	bool "S3C2410 Initialisation watchdog"
-	depends on ARCH_S3C2410 && S3C2410_WATCHDOG
-	help
-	  Say y to enable the watchdog during the kernel decompression
-	  stage. If the kernel fails to uncompress, then the watchdog
-	  will trigger a reset and the system should restart.
-
-	  Although this uses the same hardware unit as the kernel watchdog
-	  driver, it is not a replacement for it. If you use this option,
-	  you will have to use the watchdg driver to either stop the timeout
-	  or restart it. If you do not, then your kernel will reboot after
-	  startup.
-
-	  The driver uses a fixed timeout value, so the exact time till the
-	  system resets depends on the value of PCLK. The timeout on an
-	  200MHz s3c2410 should be about 30 seconds.
-
-config S3C2410_BOOT_ERROR_RESET
-	bool "S3C2410 Reboot on decompression error"
-	depends on ARCH_S3C2410
-	help
-	  Say y here to use the watchdog to reset the system if the
-	  kernel decompressor detects an error during decompression.
-
-
-comment "S3C2410 Setup"
-
-config S3C2410_DMA
-	bool "S3C2410 DMA support"
-	depends on ARCH_S3C2410
-	help
-	  S3C2410 DMA support. This is needed for drivers like sound which
-	  use the S3C2410's DMA system to move data to and from the
-	  peripheral blocks.
-
-config S3C2410_DMA_DEBUG
-	bool "S3C2410 DMA support debug"
-	depends on ARCH_S3C2410 && S3C2410_DMA
-	help
-	  Enable debugging output for the DMA code. This option sends info
-	  to the kernel log, at priority KERN_DEBUG.
-
-	  Note, it is easy to create and fill the log buffer in a small
-	  amount of time, as well as using an significant percentage of
-	  the CPU time doing so.
-
-
-config S3C2410_PM_DEBUG
-	bool "S3C2410 PM Suspend debug"
-	depends on ARCH_S3C2410 && PM
-	help
-	  Say Y here if you want verbose debugging from the PM Suspend and
-	  Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
-	  for more information.
-
-config S3C2410_PM_CHECK
-	bool "S3C2410 PM Suspend Memory CRC"
-	depends on ARCH_S3C2410 && PM && CRC32
-	help
- 	  Enable the PM code's memory area checksum over sleep. This option
-	  will generate CRCs of all blocks of memory, and store them before
-	  going to sleep. The blocks are then checked on resume for any
-	  errors.
-
-config S3C2410_PM_CHECK_CHUNKSIZE
-	int "S3C2410 PM Suspend CRC Chunksize (KiB)"
-	depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK
-	default 64
-	help
-	  Set the chunksize in Kilobytes of the CRC for checking memory
-	  corruption over suspend and resume. A smaller value will mean that
-	  the CRC data block will take more memory, but wil identify any
-	  faults with better precision.
-
-config PM_SIMTEC
-	bool
-	help
-	  Common power management code for systems that are
-	  compatible with the Simtec style of power management
-
-config S3C2410_LOWLEVEL_UART_PORT
-	int "S3C2410 UART to use for low-level messages"
-	default 0
-	help
-	  Choice of which UART port to use for the low-level messages,
-	  such as the `Uncompressing...` at start time. The value of
-	  this configuration should be between zero and two. The port
-	  must have been initialised by the boot-loader before use.
-
-	  Note, this does not affect the port used by the debug messages,
-	  which is a separate configuration.
-
-endif
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index 27663e2..9a3d3d2 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -1,92 +1,31 @@
-
+# arch/arm/mach-s3c2410/Makefile
 #
-# Makefile for the linux kernel.
+# Copyright 2007 Simtec Electronics
 #
+# Licensed under GPLv2
 
-# Object file lists.
-
-obj-y			:= cpu.o irq.o time.o gpio.o clock.o devs.o
-obj-m			:=
-obj-n			:=
-obj-			:=
-obj-dma-y		:=
-obj-dma-n		:=
-
-# DMA
-obj-$(CONFIG_S3C2410_DMA)	+= dma.o
-
-# S3C2400 support files
-obj-$(CONFIG_CPU_S3C2400)	+= s3c2400-gpio.o
-
-# S3C2410 support files
+obj-y				:=
+obj-m				:=
+obj-n				:=
+obj-				:=
 
 obj-$(CONFIG_CPU_S3C2410)	+= s3c2410.o
-obj-$(CONFIG_CPU_S3C2410)	+= s3c2410-gpio.o
-obj-$(CONFIG_CPU_S3C2410)	+= s3c2410-irq.o
+obj-$(CONFIG_CPU_S3C2410)	+= irq.o
+obj-$(CONFIG_CPU_S3C2410_DMA)	+= dma.o
+obj-$(CONFIG_CPU_S3C2410_DMA)	+= dma.o
+obj-$(CONFIG_S3C2410_PM)	+= pm.o sleep.o
+obj-$(CONFIG_S3C2410_GPIO)	+= gpio.o
+obj-$(CONFIG_S3C2410_CLOCK)	+= clock.o
 
-obj-$(CONFIG_S3C2410_PM)	+= s3c2410-pm.o s3c2410-sleep.o
-obj-$(CONFIG_CPU_S3C2410_DMA)	+= s3c2410-dma.o
+# Machine support
 
-# Power Management support
-
-obj-$(CONFIG_PM)		+= pm.o sleep.o
-obj-$(CONFIG_PM_SIMTEC)		+= pm-simtec.o
-obj-$(CONFIG_PM_H1940)		+= pm-h1940.o
-
-# S3C2412 support
-obj-$(CONFIG_CPU_S3C2412)	+= s3c2412.o
-obj-$(CONFIG_CPU_S3C2412)	+= s3c2412-irq.o
-obj-$(CONFIG_CPU_S3C2412)	+= s3c2412-clock.o
-obj-dma-$(CONFIG_CPU_S3C2412)	+= s3c2412-dma.o
-
-obj-$(CONFIG_S3C2412_PM)	+= s3c2412-pm.o
-
-#
-# S3C244X support
-
-obj-$(CONFIG_CPU_S3C244X)	+= s3c244x.o
-obj-$(CONFIG_CPU_S3C244X)	+= s3c244x-irq.o
-
-# Clock control
-
-obj-$(CONFIG_S3C2410_CLOCK)	+= s3c2410-clock.o
-
-# S3C2440 support
-
-obj-$(CONFIG_CPU_S3C2440)	+= s3c2440.o s3c2440-dsc.o
-obj-$(CONFIG_CPU_S3C2440)	+= s3c2440-irq.o
-obj-$(CONFIG_CPU_S3C2440)	+= s3c2440-clock.o
-obj-$(CONFIG_CPU_S3C2440)	+= s3c2410-gpio.o
-obj-dma-$(CONFIG_CPU_S3C2440)	+= s3c2440-dma.o
-
-# S3C2442 support
-
-obj-$(CONFIG_CPU_S3C2442)	+= s3c2442.o
-obj-$(CONFIG_CPU_S3C2442)	+= s3c2442-clock.o
-
-# bast extras
-
-obj-$(CONFIG_BAST_PC104_IRQ)	+= bast-irq.o
-
-# merge in dma objects
-
-obj-y				+= $(obj-dma-y)
-
-# machine specific support
-
-obj-$(CONFIG_MACH_AML_M5900)	+= mach-amlm5900.o
-obj-$(CONFIG_MACH_ANUBIS)	+= mach-anubis.o
-obj-$(CONFIG_MACH_OSIRIS)	+= mach-osiris.o
-obj-$(CONFIG_ARCH_BAST)		+= mach-bast.o usb-simtec.o
-obj-$(CONFIG_ARCH_H1940)	+= mach-h1940.o
-obj-$(CONFIG_MACH_N30)		+= mach-n30.o
 obj-$(CONFIG_ARCH_SMDK2410)	+= mach-smdk2410.o
-obj-$(CONFIG_MACH_SMDK2413)	+= mach-smdk2413.o
-obj-$(CONFIG_ARCH_S3C2440)	+= mach-smdk2440.o
-obj-$(CONFIG_MACH_VR1000)	+= mach-vr1000.o usb-simtec.o
-obj-$(CONFIG_MACH_RX3715)	+= mach-rx3715.o
+obj-$(CONFIG_ARCH_H1940)	+= mach-h1940.o
+obj-$(CONFIG_PM_H1940)		+= pm-h1940.o
+obj-$(CONFIG_MACH_N30)		+= mach-n30.o
+obj-$(CONFIG_ARCH_BAST)		+= mach-bast.o usb-simtec.o
 obj-$(CONFIG_MACH_OTOM)		+= mach-otom.o
-obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
-obj-$(CONFIG_MACH_VSTMS)	+= mach-vstms.o
-
-obj-$(CONFIG_MACH_SMDK)		+= common-smdk.o
\ No newline at end of file
+obj-$(CONFIG_MACH_AML_M5900)	+= mach-amlm5900.o
+obj-$(CONFIG_BAST_PC104_IRQ)	+= bast-irq.o
+obj-$(CONFIG_MACH_VR1000)	+= mach-vr1000.o usb-simtec.o
+obj-$(CONFIG_MACH_QT2410)	+= mach-qt2410.o
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
index 379efe7..daeba42 100644
--- a/arch/arm/mach-s3c2410/bast-irq.c
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -39,7 +39,7 @@
 #include <asm/arch/bast-map.h>
 #include <asm/arch/bast-irq.h>
 
-#include "irq.h"
+#include <asm/plat-s3c24xx/irq.h>
 
 #if 0
 #include <asm/debug-ll.h>
diff --git a/arch/arm/mach-s3c2410/bast.h b/arch/arm/mach-s3c2410/bast.h
index e5d0331..e985437 100644
--- a/arch/arm/mach-s3c2410/bast.h
+++ b/arch/arm/mach-s3c2410/bast.h
@@ -1,2 +1,2 @@
-
+/* linux/arch/arm/mach-s3c2410/bast.h
 extern void bast_init_irq(void);
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index e13fb67..5b4831c 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -1,15 +1,9 @@
 /* linux/arch/arm/mach-s3c2410/clock.c
  *
- * Copyright (c) 2004-2005 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
- * S3C24XX Core clock control support
- *
- * Based on, and code from linux/arch/arm/mach-versatile/clock.c
- **
- **  Copyright (C) 2004 ARM Limited.
- **  Written by Deep Blue Solutions Limited.
- *
+ * S3C2410,S3C2440,S3C2442 Clock control support
  *
  * 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
@@ -32,418 +26,251 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
 #include <linux/sysdev.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
 #include <linux/clk.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/map.h>
 
 #include <asm/hardware.h>
-#include <asm/irq.h>
 #include <asm/io.h>
 
+#include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-clock.h>
 #include <asm/arch/regs-gpio.h>
 
-#include "clock.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
-/* clock information */
-
-static LIST_HEAD(clocks);
-
-DEFINE_MUTEX(clocks_mutex);
-
-/* enable and disable calls for use with the clk struct */
-
-static int clk_null_enable(struct clk *clk, int enable)
+int s3c2410_clkcon_enable(struct clk *clk, int enable)
 {
-	return 0;
-}
+	unsigned int clocks = clk->ctrlbit;
+	unsigned long clkcon;
 
-/* Clock API calls */
-
-struct clk *clk_get(struct device *dev, const char *id)
-{
-	struct clk *p;
-	struct clk *clk = ERR_PTR(-ENOENT);
-	int idno;
-
-	if (dev == NULL || dev->bus != &platform_bus_type)
-		idno = -1;
-	else
-		idno = to_platform_device(dev)->id;
-
-	mutex_lock(&clocks_mutex);
-
-	list_for_each_entry(p, &clocks, list) {
-		if (p->id == idno &&
-		    strcmp(id, p->name) == 0 &&
-		    try_module_get(p->owner)) {
-			clk = p;
-			break;
-		}
-	}
-
-	/* check for the case where a device was supplied, but the
-	 * clock that was being searched for is not device specific */
-
-	if (IS_ERR(clk)) {
-		list_for_each_entry(p, &clocks, list) {
-			if (p->id == -1 && strcmp(id, p->name) == 0 &&
-			    try_module_get(p->owner)) {
-				clk = p;
-				break;
-			}
-		}
-	}
-
-	mutex_unlock(&clocks_mutex);
-	return clk;
-}
-
-void clk_put(struct clk *clk)
-{
-	module_put(clk->owner);
-}
-
-int clk_enable(struct clk *clk)
-{
-	if (IS_ERR(clk) || clk == NULL)
-		return -EINVAL;
-
-	clk_enable(clk->parent);
-
-	mutex_lock(&clocks_mutex);
-
-	if ((clk->usage++) == 0)
-		(clk->enable)(clk, 1);
-
-	mutex_unlock(&clocks_mutex);
-	return 0;
-}
-
-void clk_disable(struct clk *clk)
-{
-	if (IS_ERR(clk) || clk == NULL)
-		return;
-
-	mutex_lock(&clocks_mutex);
-
-	if ((--clk->usage) == 0)
-		(clk->enable)(clk, 0);
-
-	mutex_unlock(&clocks_mutex);
-	clk_disable(clk->parent);
-}
-
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	if (IS_ERR(clk))
-		return 0;
-
-	if (clk->rate != 0)
-		return clk->rate;
-
-	if (clk->get_rate != NULL)
-		return (clk->get_rate)(clk);
-
-	if (clk->parent != NULL)
-		return clk_get_rate(clk->parent);
-
-	return clk->rate;
-}
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	if (!IS_ERR(clk) && clk->round_rate)
-		return (clk->round_rate)(clk, rate);
-
-	return rate;
-}
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	int ret;
-
-	if (IS_ERR(clk))
-		return -EINVAL;
-
-	mutex_lock(&clocks_mutex);
-	ret = (clk->set_rate)(clk, rate);
-	mutex_unlock(&clocks_mutex);
-
-	return ret;
-}
-
-struct clk *clk_get_parent(struct clk *clk)
-{
-	return clk->parent;
-}
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	int ret = 0;
-
-	if (IS_ERR(clk))
-		return -EINVAL;
-
-	mutex_lock(&clocks_mutex);
-
-	if (clk->set_parent)
-		ret = (clk->set_parent)(clk, parent);
-
-	mutex_unlock(&clocks_mutex);
-
-	return ret;
-}
-
-EXPORT_SYMBOL(clk_get);
-EXPORT_SYMBOL(clk_put);
-EXPORT_SYMBOL(clk_enable);
-EXPORT_SYMBOL(clk_disable);
-EXPORT_SYMBOL(clk_get_rate);
-EXPORT_SYMBOL(clk_round_rate);
-EXPORT_SYMBOL(clk_set_rate);
-EXPORT_SYMBOL(clk_get_parent);
-EXPORT_SYMBOL(clk_set_parent);
-
-/* base clocks */
-
-struct clk clk_xtal = {
-	.name		= "xtal",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= NULL,
-	.ctrlbit	= 0,
-};
-
-struct clk clk_mpll = {
-	.name		= "mpll",
-	.id		= -1,
-};
-
-struct clk clk_upll = {
-	.name		= "upll",
-	.id		= -1,
-	.parent		= NULL,
-	.ctrlbit	= 0,
-};
-
-struct clk clk_f = {
-	.name		= "fclk",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= &clk_mpll,
-	.ctrlbit	= 0,
-};
-
-struct clk clk_h = {
-	.name		= "hclk",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= NULL,
-	.ctrlbit	= 0,
-};
-
-struct clk clk_p = {
-	.name		= "pclk",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= NULL,
-	.ctrlbit	= 0,
-};
-
-struct clk clk_usb_bus = {
-	.name		= "usb-bus",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= &clk_upll,
-};
-
-/* clocks that could be registered by external code */
-
-static int s3c24xx_dclk_enable(struct clk *clk, int enable)
-{
-	unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
+	clkcon = __raw_readl(S3C2410_CLKCON);
 
 	if (enable)
-		dclkcon |= clk->ctrlbit;
+		clkcon |= clocks;
 	else
-		dclkcon &= ~clk->ctrlbit;
+		clkcon &= ~clocks;
 
-	__raw_writel(dclkcon, S3C24XX_DCLKCON);
+	/* ensure none of the special function bits set */
+	clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
+
+	__raw_writel(clkcon, S3C2410_CLKCON);
 
 	return 0;
 }
 
-static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
+static int s3c2410_upll_enable(struct clk *clk, int enable)
 {
-	unsigned long dclkcon;
-	unsigned int uclk;
+	unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
+	unsigned long orig = clkslow;
 
-	if (parent == &clk_upll)
-		uclk = 1;
-	else if (parent == &clk_p)
-		uclk = 0;
+	if (enable)
+		clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
 	else
-		return -EINVAL;
+		clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
 
-	clk->parent = parent;
+	__raw_writel(clkslow, S3C2410_CLKSLOW);
 
-	dclkcon = __raw_readl(S3C24XX_DCLKCON);
+	/* if we started the UPLL, then allow to settle */
 
-	if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
-		if (uclk)
-			dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
-		else
-			dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
-	} else {
-		if (uclk)
-			dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
-		else
-			dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
+	if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
+		udelay(200);
+
+	return 0;
+}
+
+/* standard clock definitions */
+
+static struct clk init_clocks_disable[] = {
+	{
+		.name		= "nand",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_NAND,
+	}, {
+		.name		= "sdi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_SDI,
+	}, {
+		.name		= "adc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_ADC,
+	}, {
+		.name		= "i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_IIC,
+	}, {
+		.name		= "iis",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_IIS,
+	}, {
+		.name		= "spi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_SPI,
+	}
+};
+
+static struct clk init_clocks[] = {
+	{
+		.name		= "lcd",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_LCDC,
+	}, {
+		.name		= "gpio",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_GPIO,
+	}, {
+		.name		= "usb-host",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_USBH,
+	}, {
+		.name		= "usb-device",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_USBD,
+	}, {
+		.name		= "timers",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_PWMT,
+	}, {
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_UART0,
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_UART1,
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_UART2,
+	}, {
+		.name		= "rtc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2410_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_RTC,
+	}, {
+		.name		= "watchdog",
+		.id		= -1,
+		.parent		= &clk_p,
+		.ctrlbit	= 0,
+	}, {
+		.name		= "usb-bus-host",
+		.id		= -1,
+		.parent		= &clk_usb_bus,
+	}, {
+		.name		= "usb-bus-gadget",
+		.id		= -1,
+		.parent		= &clk_usb_bus,
+	},
+};
+
+/* s3c2410_baseclk_add()
+ *
+ * Add all the clocks used by the s3c2410 or compatible CPUs
+ * such as the S3C2440 and S3C2442.
+ *
+ * We cannot use a system device as we are needed before any
+ * of the init-calls that initialise the devices are actually
+ * done.
+*/
+
+int __init s3c2410_baseclk_add(void)
+{
+	unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
+	unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);
+	struct clk *clkp;
+	struct clk *xtal;
+	int ret;
+	int ptr;
+
+	clk_upll.enable = s3c2410_upll_enable;
+
+	if (s3c24xx_register_clock(&clk_usb_bus) < 0)
+		printk(KERN_ERR "failed to register usb bus clock\n");
+
+	/* register clocks from clock array */
+
+	clkp = init_clocks;
+	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
+		/* ensure that we note the clock state */
+
+		clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
+
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
 	}
 
-	__raw_writel(dclkcon, S3C24XX_DCLKCON);
+	/* We must be careful disabling the clocks we are not intending to
+	 * be using at boot time, as subsytems such as the LCD which do
+	 * their own DMA requests to the bus can cause the system to lockup
+	 * if they where in the middle of requesting bus access.
+	 *
+	 * Disabling the LCD clock if the LCD is active is very dangerous,
+	 * and therefore the bootloader should be careful to not enable
+	 * the LCD clock if it is not needed.
+	*/
 
-	return 0;
-}
+	/* install (and disable) the clocks we do not need immediately */
 
+	clkp = init_clocks_disable;
+	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
 
-static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
-{
-	unsigned long mask;
-	unsigned long source;
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
 
-	/* calculate the MISCCR setting for the clock */
-
-	if (parent == &clk_xtal)
-		source = S3C2410_MISCCR_CLK0_MPLL;
-	else if (parent == &clk_upll)
-		source = S3C2410_MISCCR_CLK0_UPLL;
-	else if (parent == &clk_f)
-		source = S3C2410_MISCCR_CLK0_FCLK;
-	else if (parent == &clk_h)
-		source = S3C2410_MISCCR_CLK0_HCLK;
-	else if (parent == &clk_p)
-		source = S3C2410_MISCCR_CLK0_PCLK;
-	else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
-		source = S3C2410_MISCCR_CLK0_DCLK0;
-	else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
-		source = S3C2410_MISCCR_CLK0_DCLK0;
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	if (clk == &s3c24xx_dclk0)
-		mask = S3C2410_MISCCR_CLK0_MASK;
-	else {
-		source <<= 4;
-		mask = S3C2410_MISCCR_CLK1_MASK;
+		s3c2410_clkcon_enable(clkp, 0);
 	}
 
-	s3c2410_modify_misccr(mask, source);
-	return 0;
-}
+	/* show the clock-slow value */
 
-/* external clock definitions */
+	xtal = clk_get(NULL, "xtal");
 
-struct clk s3c24xx_dclk0 = {
-	.name		= "dclk0",
-	.id		= -1,
-	.ctrlbit	= S3C2410_DCLKCON_DCLK0EN,
-	.enable	        = s3c24xx_dclk_enable,
-	.set_parent	= s3c24xx_dclk_setparent,
-};
-
-struct clk s3c24xx_dclk1 = {
-	.name		= "dclk1",
-	.id		= -1,
-	.ctrlbit	= S3C2410_DCLKCON_DCLK0EN,
-	.enable		= s3c24xx_dclk_enable,
-	.set_parent	= s3c24xx_dclk_setparent,
-};
-
-struct clk s3c24xx_clkout0 = {
-	.name		= "clkout0",
-	.id		= -1,
-	.set_parent	= s3c24xx_clkout_setparent,
-};
-
-struct clk s3c24xx_clkout1 = {
-	.name		= "clkout1",
-	.id		= -1,
-	.set_parent	= s3c24xx_clkout_setparent,
-};
-
-struct clk s3c24xx_uclk = {
-	.name		= "uclk",
-	.id		= -1,
-};
-
-/* initialise the clock system */
-
-int s3c24xx_register_clock(struct clk *clk)
-{
-	clk->owner = THIS_MODULE;
-
-	if (clk->enable == NULL)
-		clk->enable = clk_null_enable;
-
-	/* add to the list of available clocks */
-
-	mutex_lock(&clocks_mutex);
-	list_add(&clk->list, &clocks);
-	mutex_unlock(&clocks_mutex);
-
-	return 0;
-}
-
-/* initalise all the clocks */
-
-int __init s3c24xx_setup_clocks(unsigned long xtal,
-				unsigned long fclk,
-				unsigned long hclk,
-				unsigned long pclk)
-{
-	printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n");
-
-	/* initialise the main system clocks */
-
-	clk_xtal.rate = xtal;
-	clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal);
-
-	clk_mpll.rate = fclk;
-	clk_h.rate = hclk;
-	clk_p.rate = pclk;
-	clk_f.rate = fclk;
-
-	/* assume uart clocks are correctly setup */
-
-	/* register our clocks */
-
-	if (s3c24xx_register_clock(&clk_xtal) < 0)
-		printk(KERN_ERR "failed to register master xtal\n");
-
-	if (s3c24xx_register_clock(&clk_mpll) < 0)
-		printk(KERN_ERR "failed to register mpll clock\n");
-
-	if (s3c24xx_register_clock(&clk_upll) < 0)
-		printk(KERN_ERR "failed to register upll clock\n");
-
-	if (s3c24xx_register_clock(&clk_f) < 0)
-		printk(KERN_ERR "failed to register cpu fclk\n");
-
-	if (s3c24xx_register_clock(&clk_h) < 0)
-		printk(KERN_ERR "failed to register cpu hclk\n");
-
-	if (s3c24xx_register_clock(&clk_p) < 0)
-		printk(KERN_ERR "failed to register cpu pclk\n");
+	printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
+	       print_mhz(clk_get_rate(xtal) /
+			 ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
+	       (clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
+	       (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
+	       (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
 
 	return 0;
 }
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index fa860e7..67d1ad3 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -1,9 +1,9 @@
 /* linux/arch/arm/mach-s3c2410/dma.c
  *
- * Copyright (c) 2003-2005,2006 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
- * S3C2410 DMA core
+ * S3C2410 DMA selection
  *
  * http://armlinux.simtec.co.uk/
  *
@@ -12,1430 +12,170 @@
  * published by the Free Software Foundation.
 */
 
-
-#ifdef CONFIG_S3C2410_DMA_DEBUG
-#define DEBUG
-#endif
-
-#include <linux/module.h>
+#include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
 #include <linux/sysdev.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
+#include <linux/serial_core.h>
 
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
 #include <asm/dma.h>
+#include <asm/arch/dma.h>
 
-#include <asm/mach/dma.h>
-#include <asm/arch/map.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/dma.h>
 
-#include "dma.h"
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-ac97.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-sdi.h>
+#include <asm/arch/regs-iis.h>
+#include <asm/arch/regs-spi.h>
 
-/* io map for dma */
-static void __iomem *dma_base;
-static struct kmem_cache *dma_kmem;
-
-struct s3c24xx_dma_selection dma_sel;
-
-/* dma channel state information */
-struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
-
-/* debugging functions */
-
-#define BUF_MAGIC (0xcafebabe)
-
-#define dmawarn(fmt...) printk(KERN_DEBUG fmt)
-
-#define dma_regaddr(chan, reg) ((chan)->regs + (reg))
-
-#if 1
-#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg))
-#else
-static inline void
-dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
-{
-	pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
-	writel(val, dma_regaddr(chan, reg));
-}
-#endif
-
-#define dma_rdreg(chan, reg) readl((chan)->regs + (reg))
-
-/* captured register state for debug */
-
-struct s3c2410_dma_regstate {
-	unsigned long         dcsrc;
-	unsigned long         disrc;
-	unsigned long         dstat;
-	unsigned long         dcon;
-	unsigned long         dmsktrig;
+static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
+	[DMACH_XD0] = {
+		.name		= "xdreq0",
+		.channels[0]	= S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
+	},
+	[DMACH_XD1] = {
+		.name		= "xdreq1",
+		.channels[1]	= S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
+	},
+	[DMACH_SDI] = {
+		.name		= "sdi",
+		.channels[0]	= S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
+		.channels[2]	= S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
+		.channels[3]	= S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
+		.hw_addr.to	= S3C2410_PA_IIS + S3C2410_IISFIFO,
+		.hw_addr.from	= S3C2410_PA_IIS + S3C2410_IISFIFO,
+	},
+	[DMACH_SPI0] = {
+		.name		= "spi0",
+		.channels[1]	= S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
+		.hw_addr.to	= S3C2410_PA_SPI + S3C2410_SPTDAT,
+		.hw_addr.from	= S3C2410_PA_SPI + S3C2410_SPRDAT,
+	},
+	[DMACH_SPI1] = {
+		.name		= "spi1",
+		.channels[3]	= S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
+		.hw_addr.to	= S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
+		.hw_addr.from	= S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
+	},
+	[DMACH_UART0] = {
+		.name		= "uart0",
+		.channels[0]	= S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
+		.hw_addr.to	= S3C2410_PA_UART0 + S3C2410_UTXH,
+		.hw_addr.from	= S3C2410_PA_UART0 + S3C2410_URXH,
+	},
+	[DMACH_UART1] = {
+		.name		= "uart1",
+		.channels[1]	= S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
+		.hw_addr.to	= S3C2410_PA_UART1 + S3C2410_UTXH,
+		.hw_addr.from	= S3C2410_PA_UART1 + S3C2410_URXH,
+	},
+      	[DMACH_UART2] = {
+		.name		= "uart2",
+		.channels[3]	= S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
+		.hw_addr.to	= S3C2410_PA_UART2 + S3C2410_UTXH,
+		.hw_addr.from	= S3C2410_PA_UART2 + S3C2410_URXH,
+	},
+	[DMACH_TIMER] = {
+		.name		= "timer",
+		.channels[0]	= S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
+		.channels[2]	= S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
+		.channels[3]	= S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
+	},
+	[DMACH_I2S_IN] = {
+		.name		= "i2s-sdi",
+		.channels[1]	= S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
+		.channels[2]	= S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
+		.hw_addr.from	= S3C2410_PA_IIS + S3C2410_IISFIFO,
+	},
+	[DMACH_I2S_OUT] = {
+		.name		= "i2s-sdo",
+		.channels[2]	= S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
+		.hw_addr.to	= S3C2410_PA_IIS + S3C2410_IISFIFO,
+	},
+	[DMACH_USB_EP1] = {
+		.name		= "usb-ep1",
+		.channels[0]	= S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
+	},
+	[DMACH_USB_EP2] = {
+		.name		= "usb-ep2",
+		.channels[1]	= S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
+	},
+	[DMACH_USB_EP3] = {
+		.name		= "usb-ep3",
+		.channels[2]	= S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
+	},
+	[DMACH_USB_EP4] = {
+		.name		= "usb-ep4",
+		.channels[3]	=S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
+	},
 };
 
-#ifdef CONFIG_S3C2410_DMA_DEBUG
-
-/* dmadbg_showregs
- *
- * simple debug routine to print the current state of the dma registers
-*/
-
-static void
-dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs)
+static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
+			       struct s3c24xx_dma_map *map)
 {
-	regs->dcsrc    = dma_rdreg(chan, S3C2410_DMA_DCSRC);
-	regs->disrc    = dma_rdreg(chan, S3C2410_DMA_DISRC);
-	regs->dstat    = dma_rdreg(chan, S3C2410_DMA_DSTAT);
-	regs->dcon     = dma_rdreg(chan, S3C2410_DMA_DCON);
-	regs->dmsktrig = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+	chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
 }
 
-static void
-dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *chan,
-		 struct s3c2410_dma_regstate *regs)
-{
-	printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",
-	       chan->number, fname, line,
-	       regs->dcsrc, regs->disrc, regs->dstat, regs->dmsktrig,
-	       regs->dcon);
-}
-
-static void
-dmadbg_showchan(const char *fname, int line, struct s3c2410_dma_chan *chan)
-{
-	struct s3c2410_dma_regstate state;
-
-	dmadbg_capture(chan, &state);
-
-	printk(KERN_DEBUG "dma%d: %s:%d: ls=%d, cur=%p, %p %p\n",
-	       chan->number, fname, line, chan->load_state,
-	       chan->curr, chan->next, chan->end);
-
-	dmadbg_dumpregs(fname, line, chan, &state);
-}
-
-static void
-dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
-{
-	struct s3c2410_dma_regstate state;
-
-	dmadbg_capture(chan, &state);
-	dmadbg_dumpregs(fname, line, chan, &state);
-}
-
-#define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan))
-#define dbg_showchan(chan) dmadbg_showchan(__FUNCTION__, __LINE__, (chan))
-#else
-#define dbg_showregs(chan) do { } while(0)
-#define dbg_showchan(chan) do { } while(0)
-#endif /* CONFIG_S3C2410_DMA_DEBUG */
-
-static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX];
-
-/* lookup_dma_channel
- *
- * change the dma channel number given into a real dma channel id
-*/
-
-static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel)
-{
-	if (channel & DMACH_LOW_LEVEL)
-		return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
-	else
-		return dma_chan_map[channel];
-}
-
-/* s3c2410_dma_stats_timeout
- *
- * Update DMA stats from timeout info
-*/
-
-static void
-s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val)
-{
-	if (stats == NULL)
-		return;
-
-	if (val > stats->timeout_longest)
-		stats->timeout_longest = val;
-	if (val < stats->timeout_shortest)
-		stats->timeout_shortest = val;
-
-	stats->timeout_avg += val;
-}
-
-/* s3c2410_dma_waitforload
- *
- * wait for the DMA engine to load a buffer, and update the state accordingly
-*/
-
-static int
-s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)
-{
-	int timeout = chan->load_timeout;
-	int took;
-
-	if (chan->load_state != S3C2410_DMALOAD_1LOADED) {
-		printk(KERN_ERR "dma%d: s3c2410_dma_waitforload() called in loadstate %d from line %d\n", chan->number, chan->load_state, line);
-		return 0;
-	}
-
-	if (chan->stats != NULL)
-		chan->stats->loads++;
-
-	while (--timeout > 0) {
-		if ((dma_rdreg(chan, S3C2410_DMA_DSTAT) << (32-20)) != 0) {
-			took = chan->load_timeout - timeout;
-
-			s3c2410_dma_stats_timeout(chan->stats, took);
-
-			switch (chan->load_state) {
-			case S3C2410_DMALOAD_1LOADED:
-				chan->load_state = S3C2410_DMALOAD_1RUNNING;
-				break;
-
-			default:
-				printk(KERN_ERR "dma%d: unknown load_state in s3c2410_dma_waitforload() %d\n", chan->number, chan->load_state);
-			}
-
-			return 1;
-		}
-	}
-
-	if (chan->stats != NULL) {
-		chan->stats->timeout_failed++;
-	}
-
-	return 0;
-}
-
-
-
-/* s3c2410_dma_loadbuffer
- *
- * load a buffer, and update the channel state
-*/
-
-static inline int
-s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
-		       struct s3c2410_dma_buf *buf)
-{
-	unsigned long reload;
-
-	pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
-		 buf, (unsigned long)buf->data, buf->size);
-
-	if (buf == NULL) {
-		dmawarn("buffer is NULL\n");
-		return -EINVAL;
-	}
-
-	/* check the state of the channel before we do anything */
-
-	if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
-		dmawarn("load_state is S3C2410_DMALOAD_1LOADED\n");
-	}
-
-	if (chan->load_state == S3C2410_DMALOAD_1LOADED_1RUNNING) {
-		dmawarn("state is S3C2410_DMALOAD_1LOADED_1RUNNING\n");
-	}
-
-	/* it would seem sensible if we are the last buffer to not bother
-	 * with the auto-reload bit, so that the DMA engine will not try
-	 * and load another transfer after this one has finished...
-	 */
-	if (chan->load_state == S3C2410_DMALOAD_NONE) {
-		pr_debug("load_state is none, checking for noreload (next=%p)\n",
-			 buf->next);
-		reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
-	} else {
-		//pr_debug("load_state is %d => autoreload\n", chan->load_state);
-		reload = S3C2410_DCON_AUTORELOAD;
-	}
-
-	if ((buf->data & 0xf0000000) != 0x30000000) {
-		dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
-	}
-
-	writel(buf->data, chan->addr_reg);
-
-	dma_wrreg(chan, S3C2410_DMA_DCON,
-		  chan->dcon | reload | (buf->size/chan->xfer_unit));
-
-	chan->next = buf->next;
-
-	/* update the state of the channel */
-
-	switch (chan->load_state) {
-	case S3C2410_DMALOAD_NONE:
-		chan->load_state = S3C2410_DMALOAD_1LOADED;
-		break;
-
-	case S3C2410_DMALOAD_1RUNNING:
-		chan->load_state = S3C2410_DMALOAD_1LOADED_1RUNNING;
-		break;
-
-	default:
-		dmawarn("dmaload: unknown state %d in loadbuffer\n",
-			chan->load_state);
-		break;
-	}
-
-	return 0;
-}
-
-/* s3c2410_dma_call_op
- *
- * small routine to call the op routine with the given op if it has been
- * registered
-*/
-
-static void
-s3c2410_dma_call_op(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op op)
-{
-	if (chan->op_fn != NULL) {
-		(chan->op_fn)(chan, op);
-	}
-}
-
-/* s3c2410_dma_buffdone
- *
- * small wrapper to check if callback routine needs to be called, and
- * if so, call it
-*/
-
-static inline void
-s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
-		     enum s3c2410_dma_buffresult result)
-{
-#if 0
-	pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
-		 chan->callback_fn, buf, buf->id, buf->size, result);
-#endif
-
-	if (chan->callback_fn != NULL) {
-		(chan->callback_fn)(chan, buf->id, buf->size, result);
-	}
-}
-
-/* s3c2410_dma_start
- *
- * start a dma channel going
-*/
-
-static int s3c2410_dma_start(struct s3c2410_dma_chan *chan)
-{
-	unsigned long tmp;
-	unsigned long flags;
-
-	pr_debug("s3c2410_start_dma: channel=%d\n", chan->number);
-
-	local_irq_save(flags);
-
-	if (chan->state == S3C2410_DMA_RUNNING) {
-		pr_debug("s3c2410_start_dma: already running (%d)\n", chan->state);
-		local_irq_restore(flags);
-		return 0;
-	}
-
-	chan->state = S3C2410_DMA_RUNNING;
-
-	/* check wether there is anything to load, and if not, see
-	 * if we can find anything to load
-	 */
-
-	if (chan->load_state == S3C2410_DMALOAD_NONE) {
-		if (chan->next == NULL) {
-			printk(KERN_ERR "dma%d: channel has nothing loaded\n",
-			       chan->number);
-			chan->state = S3C2410_DMA_IDLE;
-			local_irq_restore(flags);
-			return -EINVAL;
-		}
-
-		s3c2410_dma_loadbuffer(chan, chan->next);
-	}
-
-	dbg_showchan(chan);
-
-	/* enable the channel */
-
-	if (!chan->irq_enabled) {
-		enable_irq(chan->irq);
-		chan->irq_enabled = 1;
-	}
-
-	/* start the channel going */
-
-	tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
-	tmp &= ~S3C2410_DMASKTRIG_STOP;
-	tmp |= S3C2410_DMASKTRIG_ON;
-	dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
-
-	pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
-
-#if 0
-	/* the dma buffer loads should take care of clearing the AUTO
-	 * reloading feature */
-	tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
-	tmp &= ~S3C2410_DCON_NORELOAD;
-	dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
-#endif
-
-	s3c2410_dma_call_op(chan, S3C2410_DMAOP_START);
-
-	dbg_showchan(chan);
-
-	/* if we've only loaded one buffer onto the channel, then chec
-	 * to see if we have another, and if so, try and load it so when
-	 * the first buffer is finished, the new one will be loaded onto
-	 * the channel */
-
-	if (chan->next != NULL) {
-		if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
-
-			if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
-				pr_debug("%s: buff not yet loaded, no more todo\n",
-					 __FUNCTION__);
-			} else {
-				chan->load_state = S3C2410_DMALOAD_1RUNNING;
-				s3c2410_dma_loadbuffer(chan, chan->next);
-			}
-
-		} else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
-			s3c2410_dma_loadbuffer(chan, chan->next);
-		}
-	}
-
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-/* s3c2410_dma_canload
- *
- * work out if we can queue another buffer into the DMA engine
-*/
-
-static int
-s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
-{
-	if (chan->load_state == S3C2410_DMALOAD_NONE ||
-	    chan->load_state == S3C2410_DMALOAD_1RUNNING)
-		return 1;
-
-	return 0;
-}
-
-/* s3c2410_dma_enqueue
- *
- * queue an given buffer for dma transfer.
- *
- * id         the device driver's id information for this buffer
- * data       the physical address of the buffer data
- * size       the size of the buffer in bytes
- *
- * If the channel is not running, then the flag S3C2410_DMAF_AUTOSTART
- * is checked, and if set, the channel is started. If this flag isn't set,
- * then an error will be returned.
- *
- * It is possible to queue more than one DMA buffer onto a channel at
- * once, and the code will deal with the re-loading of the next buffer
- * when necessary.
-*/
-
-int s3c2410_dma_enqueue(unsigned int channel, void *id,
-			dma_addr_t data, int size)
-{
-	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-	struct s3c2410_dma_buf *buf;
-	unsigned long flags;
-
-	if (chan == NULL)
-		return -EINVAL;
-
-	pr_debug("%s: id=%p, data=%08x, size=%d\n",
-		 __FUNCTION__, id, (unsigned int)data, size);
-
-	buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
-	if (buf == NULL) {
-		pr_debug("%s: out of memory (%ld alloc)\n",
-			 __FUNCTION__, (long)sizeof(*buf));
-		return -ENOMEM;
-	}
-
-	//pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);
-	//dbg_showchan(chan);
-
-	buf->next  = NULL;
-	buf->data  = buf->ptr = data;
-	buf->size  = size;
-	buf->id    = id;
-	buf->magic = BUF_MAGIC;
-
-	local_irq_save(flags);
-
-	if (chan->curr == NULL) {
-		/* we've got nothing loaded... */
-		pr_debug("%s: buffer %p queued onto empty channel\n",
-			 __FUNCTION__, buf);
-
-		chan->curr = buf;
-		chan->end  = buf;
-		chan->next = NULL;
-	} else {
-		pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
-			 chan->number, __FUNCTION__, buf);
-
-		if (chan->end == NULL)
-			pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
-				 chan->number, __FUNCTION__, chan);
-
-		chan->end->next = buf;
-		chan->end = buf;
-	}
-
-	/* if necessary, update the next buffer field */
-	if (chan->next == NULL)
-		chan->next = buf;
-
-	/* check to see if we can load a buffer */
-	if (chan->state == S3C2410_DMA_RUNNING) {
-		if (chan->load_state == S3C2410_DMALOAD_1LOADED && 1) {
-			if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
-				printk(KERN_ERR "dma%d: loadbuffer:"
-				       "timeout loading buffer\n",
-				       chan->number);
-				dbg_showchan(chan);
-				local_irq_restore(flags);
-				return -EINVAL;
-			}
-		}
-
-		while (s3c2410_dma_canload(chan) && chan->next != NULL) {
-			s3c2410_dma_loadbuffer(chan, chan->next);
-		}
-	} else if (chan->state == S3C2410_DMA_IDLE) {
-		if (chan->flags & S3C2410_DMAF_AUTOSTART) {
-			s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_START);
-		}
-	}
-
-	local_irq_restore(flags);
-	return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_enqueue);
-
-static inline void
-s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
-{
-	int magicok = (buf->magic == BUF_MAGIC);
-
-	buf->magic = -1;
-
-	if (magicok) {
-		kmem_cache_free(dma_kmem, buf);
-	} else {
-		printk("s3c2410_dma_freebuf: buff %p with bad magic\n", buf);
-	}
-}
-
-/* s3c2410_dma_lastxfer
- *
- * called when the system is out of buffers, to ensure that the channel
- * is prepared for shutdown.
-*/
-
-static inline void
-s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
-{
-#if 0
-	pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
-		 chan->number, chan->load_state);
-#endif
-
-	switch (chan->load_state) {
-	case S3C2410_DMALOAD_NONE:
-		break;
-
-	case S3C2410_DMALOAD_1LOADED:
-		if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
-				/* flag error? */
-			printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
-			       chan->number, __FUNCTION__);
-			return;
-		}
-		break;
-
-	case S3C2410_DMALOAD_1LOADED_1RUNNING:
-		/* I belive in this case we do not have anything to do
-		 * until the next buffer comes along, and we turn off the
-		 * reload */
-		return;
-
-	default:
-		pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
-			 chan->number, chan->load_state);
-		return;
-
-	}
-
-	/* hopefully this'll shut the damned thing up after the transfer... */
-	dma_wrreg(chan, S3C2410_DMA_DCON, chan->dcon | S3C2410_DCON_NORELOAD);
-}
-
-
-#define dmadbg2(x...)
-
-static irqreturn_t
-s3c2410_dma_irq(int irq, void *devpw)
-{
-	struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw;
-	struct s3c2410_dma_buf  *buf;
-
-	buf = chan->curr;
-
-	dbg_showchan(chan);
-
-	/* modify the channel state */
-
-	switch (chan->load_state) {
-	case S3C2410_DMALOAD_1RUNNING:
-		/* TODO - if we are running only one buffer, we probably
-		 * want to reload here, and then worry about the buffer
-		 * callback */
-
-		chan->load_state = S3C2410_DMALOAD_NONE;
-		break;
-
-	case S3C2410_DMALOAD_1LOADED:
-		/* iirc, we should go back to NONE loaded here, we
-		 * had a buffer, and it was never verified as being
-		 * loaded.
-		 */
-
-		chan->load_state = S3C2410_DMALOAD_NONE;
-		break;
-
-	case S3C2410_DMALOAD_1LOADED_1RUNNING:
-		/* we'll worry about checking to see if another buffer is
-		 * ready after we've called back the owner. This should
-		 * ensure we do not wait around too long for the DMA
-		 * engine to start the next transfer
-		 */
-
-		chan->load_state = S3C2410_DMALOAD_1LOADED;
-		break;
-
-	case S3C2410_DMALOAD_NONE:
-		printk(KERN_ERR "dma%d: IRQ with no loaded buffer?\n",
-		       chan->number);
-		break;
-
-	default:
-		printk(KERN_ERR "dma%d: IRQ in invalid load_state %d\n",
-		       chan->number, chan->load_state);
-		break;
-	}
-
-	if (buf != NULL) {
-		/* update the chain to make sure that if we load any more
-		 * buffers when we call the callback function, things should
-		 * work properly */
-
-		chan->curr = buf->next;
-		buf->next  = NULL;
-
-		if (buf->magic != BUF_MAGIC) {
-			printk(KERN_ERR "dma%d: %s: buf %p incorrect magic\n",
-			       chan->number, __FUNCTION__, buf);
-			return IRQ_HANDLED;
-		}
-
-		s3c2410_dma_buffdone(chan, buf, S3C2410_RES_OK);
-
-		/* free resouces */
-		s3c2410_dma_freebuf(buf);
-	} else {
-	}
-
-	/* only reload if the channel is still running... our buffer done
-	 * routine may have altered the state by requesting the dma channel
-	 * to stop or shutdown... */
-
-	/* todo: check that when the channel is shut-down from inside this
-	 * function, we cope with unsetting reload, etc */
-
-	if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
-		unsigned long flags;
-
-		switch (chan->load_state) {
-		case S3C2410_DMALOAD_1RUNNING:
-			/* don't need to do anything for this state */
-			break;
-
-		case S3C2410_DMALOAD_NONE:
-			/* can load buffer immediately */
-			break;
-
-		case S3C2410_DMALOAD_1LOADED:
-			if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
-				/* flag error? */
-				printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
-				       chan->number, __FUNCTION__);
-				return IRQ_HANDLED;
-			}
-
-			break;
-
-		case S3C2410_DMALOAD_1LOADED_1RUNNING:
-			goto no_load;
-
-		default:
-			printk(KERN_ERR "dma%d: unknown load_state in irq, %d\n",
-			       chan->number, chan->load_state);
-			return IRQ_HANDLED;
-		}
-
-		local_irq_save(flags);
-		s3c2410_dma_loadbuffer(chan, chan->next);
-		local_irq_restore(flags);
-	} else {
-		s3c2410_dma_lastxfer(chan);
-
-		/* see if we can stop this channel.. */
-		if (chan->load_state == S3C2410_DMALOAD_NONE) {
-			pr_debug("dma%d: end of transfer, stopping channel (%ld)\n",
-				 chan->number, jiffies);
-			s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
-					 S3C2410_DMAOP_STOP);
-		}
-	}
-
- no_load:
-	return IRQ_HANDLED;
-}
-
-static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel);
-
-/* s3c2410_request_dma
- *
- * get control of an dma channel
-*/
-
-int s3c2410_dma_request(unsigned int channel,
-			struct s3c2410_dma_client *client,
-			void *dev)
-{
-	struct s3c2410_dma_chan *chan;
-	unsigned long flags;
-	int err;
-
-	pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
-		 channel, client->name, dev);
-
-	local_irq_save(flags);
-
-	chan = s3c2410_dma_map_channel(channel);
-	if (chan == NULL) {
-		local_irq_restore(flags);
-		return -EBUSY;
-	}
-
-	dbg_showchan(chan);
-
-	chan->client = client;
-	chan->in_use = 1;
-
-	if (!chan->irq_claimed) {
-		pr_debug("dma%d: %s : requesting irq %d\n",
-			 channel, __FUNCTION__, chan->irq);
-
-		chan->irq_claimed = 1;
-		local_irq_restore(flags);
-
-		err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
-				  client->name, (void *)chan);
-
-		local_irq_save(flags);
-
-		if (err) {
-			chan->in_use = 0;
-			chan->irq_claimed = 0;
-			local_irq_restore(flags);
-
-			printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",
-			       client->name, chan->irq, chan->number);
-			return err;
-		}
-
-		chan->irq_enabled = 1;
-	}
-
-	local_irq_restore(flags);
-
-	/* need to setup */
-
-	pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan);
-
-	return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_request);
-
-/* s3c2410_dma_free
- *
- * release the given channel back to the system, will stop and flush
- * any outstanding transfers, and ensure the channel is ready for the
- * next claimant.
- *
- * Note, although a warning is currently printed if the freeing client
- * info is not the same as the registrant's client info, the free is still
- * allowed to go through.
-*/
-
-int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client)
-{
-	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-	unsigned long flags;
-
-	if (chan == NULL)
-		return -EINVAL;
-
-	local_irq_save(flags);
-
-	if (chan->client != client) {
-		printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
-		       channel, chan->client, client);
-	}
-
-	/* sort out stopping and freeing the channel */
-
-	if (chan->state != S3C2410_DMA_IDLE) {
-		pr_debug("%s: need to stop dma channel %p\n",
-		       __FUNCTION__, chan);
-
-		/* possibly flush the channel */
-		s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STOP);
-	}
-
-	chan->client = NULL;
-	chan->in_use = 0;
-
-	if (chan->irq_claimed)
-		free_irq(chan->irq, (void *)chan);
-
-	chan->irq_claimed = 0;
-
-	if (!(channel & DMACH_LOW_LEVEL))
-		dma_chan_map[channel] = NULL;
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_free);
-
-static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
-{
-	unsigned long flags;
-	unsigned long tmp;
-
-	pr_debug("%s:\n", __FUNCTION__);
-
-	dbg_showchan(chan);
-
-	local_irq_save(flags);
-
-	s3c2410_dma_call_op(chan,  S3C2410_DMAOP_STOP);
-
-	tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
-	tmp |= S3C2410_DMASKTRIG_STOP;
-	//tmp &= ~S3C2410_DMASKTRIG_ON;
-	dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
-
-#if 0
-	/* should also clear interrupts, according to WinCE BSP */
-	tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
-	tmp |= S3C2410_DCON_NORELOAD;
-	dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
-#endif
-
-	/* should stop do this, or should we wait for flush? */
-	chan->state      = S3C2410_DMA_IDLE;
-	chan->load_state = S3C2410_DMALOAD_NONE;
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
-{
-	unsigned long tmp;
-	unsigned int timeout = 0x10000;
-
-	while (timeout-- > 0) {
-		tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
-
-		if (!(tmp & S3C2410_DMASKTRIG_ON))
-			return;
-	}
-
-	pr_debug("dma%d: failed to stop?\n", chan->number);
-}
-
-
-/* s3c2410_dma_flush
- *
- * stop the channel, and remove all current and pending transfers
-*/
-
-static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
-{
-	struct s3c2410_dma_buf *buf, *next;
-	unsigned long flags;
-
-	pr_debug("%s: chan %p (%d)\n", __FUNCTION__, chan, chan->number);
-
-	dbg_showchan(chan);
-
-	local_irq_save(flags);
-
-	if (chan->state != S3C2410_DMA_IDLE) {
-		pr_debug("%s: stopping channel...\n", __FUNCTION__ );
-		s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP);
-	}
-
-	buf = chan->curr;
-	if (buf == NULL)
-		buf = chan->next;
-
-	chan->curr = chan->next = chan->end = NULL;
-
-	if (buf != NULL) {
-		for ( ; buf != NULL; buf = next) {
-			next = buf->next;
-
-			pr_debug("%s: free buffer %p, next %p\n",
-			       __FUNCTION__, buf, buf->next);
-
-			s3c2410_dma_buffdone(chan, buf, S3C2410_RES_ABORT);
-			s3c2410_dma_freebuf(buf);
-		}
-	}
-
-	dbg_showregs(chan);
-
-	s3c2410_dma_waitforstop(chan);
-
-#if 0
-	/* should also clear interrupts, according to WinCE BSP */
-	{
-		unsigned long tmp;
-
-		tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
-		tmp |= S3C2410_DCON_NORELOAD;
-		dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
-	}
-#endif
-
-	dbg_showregs(chan);
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-int
-s3c2410_dma_started(struct s3c2410_dma_chan *chan)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-
-	dbg_showchan(chan);
-
-	/* if we've only loaded one buffer onto the channel, then chec
-	 * to see if we have another, and if so, try and load it so when
-	 * the first buffer is finished, the new one will be loaded onto
-	 * the channel */
-
-	if (chan->next != NULL) {
-		if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
-
-			if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
-				pr_debug("%s: buff not yet loaded, no more todo\n",
-					 __FUNCTION__);
-			} else {
-				chan->load_state = S3C2410_DMALOAD_1RUNNING;
-				s3c2410_dma_loadbuffer(chan, chan->next);
-			}
-
-		} else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
-			s3c2410_dma_loadbuffer(chan, chan->next);
-		}
-	}
-
-
-	local_irq_restore(flags);
-
-	return 0;
-
-}
-
-int
-s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op)
-{
-	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-
-	if (chan == NULL)
-		return -EINVAL;
-
-	switch (op) {
-	case S3C2410_DMAOP_START:
-		return s3c2410_dma_start(chan);
-
-	case S3C2410_DMAOP_STOP:
-		return s3c2410_dma_dostop(chan);
-
-	case S3C2410_DMAOP_PAUSE:
-	case S3C2410_DMAOP_RESUME:
-		return -ENOENT;
-
-	case S3C2410_DMAOP_FLUSH:
-		return s3c2410_dma_flush(chan);
-
-	case S3C2410_DMAOP_STARTED:
-		return s3c2410_dma_started(chan);
-
-	case S3C2410_DMAOP_TIMEOUT:
-		return 0;
-
-	}
-
-	return -ENOENT;      /* unknown, don't bother */
-}
-
-EXPORT_SYMBOL(s3c2410_dma_ctrl);
-
-/* DMA configuration for each channel
- *
- * DISRCC -> source of the DMA (AHB,APB)
- * DISRC  -> source address of the DMA
- * DIDSTC -> destination of the DMA (AHB,APD)
- * DIDST  -> destination address of the DMA
-*/
-
-/* s3c2410_dma_config
- *
- * xfersize:     size of unit in bytes (1,2,4)
- * dcon:         base value of the DCONx register
-*/
-
-int s3c2410_dma_config(dmach_t channel,
-		       int xferunit,
-		       int dcon)
-{
-	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-
-	pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
-		 __FUNCTION__, channel, xferunit, dcon);
-
-	if (chan == NULL)
-		return -EINVAL;
-
-	pr_debug("%s: Initial dcon is %08x\n", __FUNCTION__, dcon);
-
-	dcon |= chan->dcon & dma_sel.dcon_mask;
-
-	pr_debug("%s: New dcon is %08x\n", __FUNCTION__, dcon);
-
-	switch (xferunit) {
-	case 1:
-		dcon |= S3C2410_DCON_BYTE;
-		break;
-
-	case 2:
-		dcon |= S3C2410_DCON_HALFWORD;
-		break;
-
-	case 4:
-		dcon |= S3C2410_DCON_WORD;
-		break;
-
-	default:
-		pr_debug("%s: bad transfer size %d\n", __FUNCTION__, xferunit);
-		return -EINVAL;
-	}
-
-	dcon |= S3C2410_DCON_HWTRIG;
-	dcon |= S3C2410_DCON_INTREQ;
-
-	pr_debug("%s: dcon now %08x\n", __FUNCTION__, dcon);
-
-	chan->dcon = dcon;
-	chan->xfer_unit = xferunit;
-
-	return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_config);
-
-int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
-{
-	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-
-	if (chan == NULL)
-		return -EINVAL;
-
-	pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags);
-
-	chan->flags = flags;
-
-	return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_setflags);
-
-
-/* do we need to protect the settings of the fields from
- * irq?
-*/
-
-int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn)
-{
-	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-
-	if (chan == NULL)
-		return -EINVAL;
-
-	pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn);
-
-	chan->op_fn = rtn;
-
-	return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_set_opfn);
-
-int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
-{
-	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-
-	if (chan == NULL)
-		return -EINVAL;
-
-	pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn);
-
-	chan->callback_fn = rtn;
-
-	return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
-
-/* s3c2410_dma_devconfig
- *
- * configure the dma source/destination hardware type and address
- *
- * source:    S3C2410_DMASRC_HW: source is hardware
- *            S3C2410_DMASRC_MEM: source is memory
- *
- * hwcfg:     the value for xxxSTCn register,
- *            bit 0: 0=increment pointer, 1=leave pointer
- *            bit 1: 0=soucre is AHB, 1=soucre is APB
- *
- * devaddr:   physical address of the source
-*/
-
-int s3c2410_dma_devconfig(int channel,
-			  enum s3c2410_dmasrc source,
-			  int hwcfg,
-			  unsigned long devaddr)
-{
-	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-
-	if (chan == NULL)
-		return -EINVAL;
-
-	pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n",
-		 __FUNCTION__, (int)source, hwcfg, devaddr);
-
-	chan->source = source;
-	chan->dev_addr = devaddr;
-
-	switch (source) {
-	case S3C2410_DMASRC_HW:
-		/* source is hardware */
-		pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
-			 __FUNCTION__, devaddr, hwcfg);
-		dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);
-		dma_wrreg(chan, S3C2410_DMA_DISRC,  devaddr);
-		dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
-
-		chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
-		return 0;
-
-	case S3C2410_DMASRC_MEM:
-		/* source is memory */
-		pr_debug( "%s: mem source, devaddr=%08lx, hwcfg=%d\n",
-			  __FUNCTION__, devaddr, hwcfg);
-		dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
-		dma_wrreg(chan, S3C2410_DMA_DIDST,  devaddr);
-		dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
-
-		chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
-		return 0;
-	}
-
-	printk(KERN_ERR "dma%d: invalid source type (%d)\n", channel, source);
-	return -EINVAL;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_devconfig);
-
-/* s3c2410_dma_getposition
- *
- * returns the current transfer points for the dma source and destination
-*/
-
-int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
-{
- 	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-
-	if (chan == NULL)
-		return -EINVAL;
-
-	if (src != NULL)
- 		*src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
-
- 	if (dst != NULL)
- 		*dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
-
- 	return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_getposition);
-
-
-/* system device class */
-
-#ifdef CONFIG_PM
-
-static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
-{
-	struct s3c2410_dma_chan *cp = container_of(dev, struct s3c2410_dma_chan, dev);
-
-	printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
-
-	if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) {
-		/* the dma channel is still working, which is probably
-		 * a bad thing to do over suspend/resume. We stop the
-		 * channel and assume that the client is either going to
-		 * retry after resume, or that it is broken.
-		 */
-
-		printk(KERN_INFO "dma: stopping channel %d due to suspend\n",
-		       cp->number);
-
-		s3c2410_dma_dostop(cp);
-	}
-
-	return 0;
-}
-
-static int s3c2410_dma_resume(struct sys_device *dev)
-{
-	return 0;
-}
-
-#else
-#define s3c2410_dma_suspend NULL
-#define s3c2410_dma_resume  NULL
-#endif /* CONFIG_PM */
-
-struct sysdev_class dma_sysclass = {
-	set_kset_name("s3c24xx-dma"),
-	.suspend	= s3c2410_dma_suspend,
-	.resume		= s3c2410_dma_resume,
+static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
+	.select		= s3c2410_dma_select,
+	.dcon_mask	= 7 << 24,
+	.map		= s3c2410_dma_mappings,
+	.map_size	= ARRAY_SIZE(s3c2410_dma_mappings),
 };
 
-/* kmem cache implementation */
+static struct s3c24xx_dma_order __initdata s3c2410_dma_order = {
+	.channels	= {
+		[DMACH_SDI]	= {
+			.list	= {
+				[0]	= 3 | DMA_CH_VALID,
+				[1]	= 2 | DMA_CH_VALID,
+				[2]	= 0 | DMA_CH_VALID,
+			},
+		},
+		[DMACH_I2S_IN]	= {
+			.list	= {
+				[0]	= 1 | DMA_CH_VALID,
+				[1]	= 2 | DMA_CH_VALID,
+			},
+		},
+	},
+};
 
-static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long f)
+static int s3c2410_dma_add(struct sys_device *sysdev)
 {
-	memset(p, 0, sizeof(struct s3c2410_dma_buf));
+	s3c2410_dma_init();
+	s3c24xx_dma_order_set(&s3c2410_dma_order);
+	return s3c24xx_dma_init_map(&s3c2410_dma_sel);
 }
 
-/* initialisation code */
+#if defined(CONFIG_CPU_S3C2410)
+static struct sysdev_driver s3c2410_dma_driver = {
+	.add	= s3c2410_dma_add,
+};
 
-static int __init s3c2410_init_dma(void)
+static int __init s3c2410_dma_drvinit(void)
 {
-	struct s3c2410_dma_chan *cp;
-	int channel;
-	int ret;
-
-	printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n");
-
-	dma_base = ioremap(S3C24XX_PA_DMA, 0x200);
-	if (dma_base == NULL) {
-		printk(KERN_ERR "dma failed to remap register block\n");
-		return -ENOMEM;
-	}
-
-	printk("Registering sysclass\n");
-
-	ret = sysdev_class_register(&dma_sysclass);
-	if (ret != 0) {
-		printk(KERN_ERR "dma sysclass registration failed\n");
-		goto err;
-	}
-
-	dma_kmem = kmem_cache_create("dma_desc", sizeof(struct s3c2410_dma_buf), 0,
-				     SLAB_HWCACHE_ALIGN,
-				     s3c2410_dma_cache_ctor, NULL);
-
-	if (dma_kmem == NULL) {
-		printk(KERN_ERR "dma failed to make kmem cache\n");
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) {
-		cp = &s3c2410_chans[channel];
-
-		memset(cp, 0, sizeof(struct s3c2410_dma_chan));
-
-		/* dma channel irqs are in order.. */
-		cp->number = channel;
-		cp->irq    = channel + IRQ_DMA0;
-		cp->regs   = dma_base + (channel*0x40);
-
-		/* point current stats somewhere */
-		cp->stats  = &cp->stats_store;
-		cp->stats_store.timeout_shortest = LONG_MAX;
-
-		/* basic channel configuration */
-
-		cp->load_timeout = 1<<18;
-
-		/* register system device */
-
-		cp->dev.cls = &dma_sysclass;
-		cp->dev.id  = channel;
-		ret = sysdev_register(&cp->dev);
-
-		printk("DMA channel %d at %p, irq %d\n",
-		       cp->number, cp->regs, cp->irq);
-	}
-
-	return 0;
-
- err:
-	kmem_cache_destroy(dma_kmem);
-	iounmap(dma_base);
-	dma_base = NULL;
-	return ret;
+	return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver);
 }
 
-core_initcall(s3c2410_init_dma);
+arch_initcall(s3c2410_dma_drvinit);
+#endif
 
-static inline int is_channel_valid(unsigned int channel)
+#if defined(CONFIG_CPU_S3C2442)
+/* S3C2442 DMA contains the same selection table as the S3C2410 */
+static struct sysdev_driver s3c2442_dma_driver = {
+	.add	= s3c2410_dma_add,
+};
+
+static int __init s3c2442_dma_drvinit(void)
 {
-	return (channel & DMA_CH_VALID);
+	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver);
 }
 
-/* s3c2410_dma_map_channel()
- *
- * turn the virtual channel number into a real, and un-used hardware
- * channel.
- *
- * currently this code uses first-free channel from the specified harware
- * map, not taking into account anything that the board setup code may
- * have to say about the likely peripheral set to be in use.
-*/
+arch_initcall(s3c2442_dma_drvinit);
+#endif
 
-struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
-{
-	struct s3c24xx_dma_map *ch_map;
-	struct s3c2410_dma_chan *dmach;
-	int ch;
-
-	if (dma_sel.map == NULL || channel > dma_sel.map_size)
-		return NULL;
-
-	ch_map = dma_sel.map + channel;
-
-	for (ch = 0; ch < S3C2410_DMA_CHANNELS; ch++) {
-		if (!is_channel_valid(ch_map->channels[ch]))
-			continue;
-
-		if (s3c2410_chans[ch].in_use == 0) {
-			printk("mapped channel %d to %d\n", channel, ch);
-			break;
-		}
-	}
-
-	if (ch >= S3C2410_DMA_CHANNELS)
-		return NULL;
-
-	/* update our channel mapping */
-
-	dmach = &s3c2410_chans[ch];
-	dma_chan_map[channel] = dmach;
-
-	/* select the channel */
-
-	(dma_sel.select)(dmach, ch_map);
-
-	return dmach;
-}
-
-static void s3c24xx_dma_show_ch(struct s3c24xx_dma_map *map, int ch)
-{
-	/* show the channel configuration */
-
-	printk("%2d: %20s, channels %c%c%c%c\n", ch, map->name,
-	       (is_channel_valid(map->channels[0]) ? '0' : '-'),
-	       (is_channel_valid(map->channels[1]) ? '1' : '-'),
-	       (is_channel_valid(map->channels[2]) ? '2' : '-'),
-	       (is_channel_valid(map->channels[3]) ? '3' : '-'));
-}
-
-static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch)
-{
-	if (1)
-		s3c24xx_dma_show_ch(map, ch);
-
-	return 0;
-}
-
-int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
-{
-	struct s3c24xx_dma_map *nmap;
-	size_t map_sz = sizeof(*nmap) * sel->map_size;
-	int ptr;
-
-	nmap = kmalloc(map_sz, GFP_KERNEL);
-	if (nmap == NULL)
-		return -ENOMEM;
-
-	memcpy(nmap, sel->map, map_sz);
-	memcpy(&dma_sel, sel, sizeof(*sel));
-
-	dma_sel.map = nmap;
-
-	for (ptr = 0; ptr < sel->map_size; ptr++)
-		s3c24xx_dma_check_entry(nmap+ptr, ptr);
-
-	return 0;
-}
diff --git a/arch/arm/mach-s3c2410/dma.h b/arch/arm/mach-s3c2410/dma.h
deleted file mode 100644
index 0ebfe0a..0000000
--- a/arch/arm/mach-s3c2410/dma.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* arch/arm/mach-s3c2410/dma.h
- *
- * Copyright (C) 2006 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C24XX DMA support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-extern struct sysdev_class dma_sysclass;
-extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
-
-#define DMA_CH_VALID		(1<<31)
-
-struct s3c24xx_dma_addr {
-	unsigned long		from;
-	unsigned long		to;
-};
-
-/* struct s3c24xx_dma_map
- *
- * this holds the mapping information for the channel selected
- * to be connected to the specified device
-*/
-
-struct s3c24xx_dma_map {
-	const char		*name;
-	struct s3c24xx_dma_addr  hw_addr;
-
-	unsigned long		 channels[S3C2410_DMA_CHANNELS];
-};
-
-struct s3c24xx_dma_selection {
-	struct s3c24xx_dma_map	*map;
-	unsigned long		 map_size;
-	unsigned long		 dcon_mask;
-
-	void	(*select)(struct s3c2410_dma_chan *chan,
-			  struct s3c24xx_dma_map *map);
-};
-
-extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c
index f6fb215..01e795d 100644
--- a/arch/arm/mach-s3c2410/gpio.c
+++ b/arch/arm/mach-s3c2410/gpio.c
@@ -1,9 +1,9 @@
 /* linux/arch/arm/mach-s3c2410/gpio.c
  *
- * Copyright (c) 2004-2005 Simtec Electronics
+ * Copyright (c) 2004-2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
- * S3C24XX GPIO support
+ * S3C2410 GPIO support
  *
  * 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
@@ -18,8 +18,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
+ */
 
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -33,156 +32,40 @@
 
 #include <asm/arch/regs-gpio.h>
 
-void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
+int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
+			   unsigned int config)
 {
-	void __iomem *base = S3C24XX_GPIO_BASE(pin);
-	unsigned long mask;
-	unsigned long con;
+	void __iomem *reg = S3C24XX_EINFLT0;
 	unsigned long flags;
+	unsigned long val;
 
-	if (pin < S3C2410_GPIO_BANKB) {
-		mask = 1 << S3C2410_GPIO_OFFSET(pin);
-	} else {
-		mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
-	}
+	if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15)
+		return -1;
 
-	switch (function) {
-	case S3C2410_GPIO_LEAVE:
-		mask = 0;
-		function = 0;
-		break;
+	config &= 0xff;
 
-	case S3C2410_GPIO_INPUT:
-	case S3C2410_GPIO_OUTPUT:
-	case S3C2410_GPIO_SFN2:
-	case S3C2410_GPIO_SFN3:
-		if (pin < S3C2410_GPIO_BANKB) {
-			function -= 1;
-			function &= 1;
-			function <<= S3C2410_GPIO_OFFSET(pin);
-		} else {
-			function &= 3;
-			function <<= S3C2410_GPIO_OFFSET(pin)*2;
-		}
-	}
-
-	/* modify the specified register wwith IRQs off */
+	pin -= S3C2410_GPG8;
+	reg += pin & ~3;
 
 	local_irq_save(flags);
 
-	con  = __raw_readl(base + 0x00);
-	con &= ~mask;
-	con |= function;
+	/* update filter width and clock source */
 
-	__raw_writel(con, base + 0x00);
+	val = __raw_readl(reg);
+	val &= ~(0xff << ((pin & 3) * 8));
+	val |= config << ((pin & 3) * 8);
+	__raw_writel(val, reg);
+
+	/* update filter enable */
+
+	val = __raw_readl(S3C24XX_EXTINT2);
+	val &= ~(1 << ((pin * 4) + 3));
+	val |= on << ((pin * 4) + 3);
+	__raw_writel(val, S3C24XX_EXTINT2);
 
 	local_irq_restore(flags);
+
+	return 0;
 }
 
-EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
-
-unsigned int s3c2410_gpio_getcfg(unsigned int pin)
-{
-	void __iomem *base = S3C24XX_GPIO_BASE(pin);
-	unsigned long val = __raw_readl(base);
-
-	if (pin < S3C2410_GPIO_BANKB) {
-		val >>= S3C2410_GPIO_OFFSET(pin);
-		val &= 1;
-		val += 1;
-	} else {
-		val >>= S3C2410_GPIO_OFFSET(pin)*2;
-		val &= 3;
-	}
-
-	return val | S3C2410_GPIO_INPUT;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getcfg);
-
-void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
-{
-	void __iomem *base = S3C24XX_GPIO_BASE(pin);
-	unsigned long offs = S3C2410_GPIO_OFFSET(pin);
-	unsigned long flags;
-	unsigned long up;
-
-	if (pin < S3C2410_GPIO_BANKB)
-		return;
-
-	local_irq_save(flags);
-
-	up = __raw_readl(base + 0x08);
-	up &= ~(1L << offs);
-	up |= to << offs;
-	__raw_writel(up, base + 0x08);
-
-	local_irq_restore(flags);
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_pullup);
-
-void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
-{
-	void __iomem *base = S3C24XX_GPIO_BASE(pin);
-	unsigned long offs = S3C2410_GPIO_OFFSET(pin);
-	unsigned long flags;
-	unsigned long dat;
-
-	local_irq_save(flags);
-
-	dat = __raw_readl(base + 0x04);
-	dat &= ~(1 << offs);
-	dat |= to << offs;
-	__raw_writel(dat, base + 0x04);
-
-	local_irq_restore(flags);
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_setpin);
-
-unsigned int s3c2410_gpio_getpin(unsigned int pin)
-{
-	void __iomem *base = S3C24XX_GPIO_BASE(pin);
-	unsigned long offs = S3C2410_GPIO_OFFSET(pin);
-
-	return __raw_readl(base + 0x04) & (1<< offs);
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getpin);
-
-unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
-{
-	unsigned long flags;
-	unsigned long misccr;
-
-	local_irq_save(flags);
-	misccr = __raw_readl(S3C24XX_MISCCR);
-	misccr &= ~clear;
-	misccr ^= change;
-	__raw_writel(misccr, S3C24XX_MISCCR);
-	local_irq_restore(flags);
-
-	return misccr;
-}
-
-EXPORT_SYMBOL(s3c2410_modify_misccr);
-
-int s3c2410_gpio_getirq(unsigned int pin)
-{
-	if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15)
-		return -1;	/* not valid interrupts */
-
-	if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
-		return -1;	/* not valid pin */
-
-	if (pin < S3C2410_GPF4)
-		return (pin - S3C2410_GPF0) + IRQ_EINT0;
-
-	if (pin < S3C2410_GPG0)
-		return (pin - S3C2410_GPF4) + IRQ_EINT4;
-
-	return (pin - S3C2410_GPG0) + IRQ_EINT8;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getirq);
+EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
index 3c0ed78..53cbdaa 100644
--- a/arch/arm/mach-s3c2410/irq.c
+++ b/arch/arm/mach-s3c2410/irq.c
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/irq.c
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -17,37 +17,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Changelog:
- *
- *   22-Jul-2004  Ben Dooks <ben@simtec.co.uk>
- *                Fixed compile warnings
- *
- *   22-Jul-2004  Roc Wu <cooloney@yahoo.com.cn>
- *                Fixed s3c_extirq_type
- *
- *   21-Jul-2004  Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
- *                Addition of ADC/TC demux
- *
- *   04-Oct-2004  Klaus Fetscher <k.fetscher@fetron.de>
- *		  Fix for set_irq_type() on low EINT numbers
- *
- *   05-Oct-2004  Ben Dooks <ben@simtec.co.uk>
- *		  Tidy up KF's patch and sort out new release
- *
- *   05-Oct-2004  Ben Dooks <ben@simtec.co.uk>
- *		  Add support for power management controls
- *
- *   04-Nov-2004  Ben Dooks
- *		  Fix standard IRQ wake for EINT0..4 and RTC
- *
- *   22-Feb-2005  Ben Dooks
- *		  Fixed edge-triggering on ADC IRQ
- *
- *   28-Jun-2005  Ben Dooks
- *		  Mark IRQ_LCD valid
- *
- *   25-Jul-2005  Ben Dooks
- *		  Split the S3C2440 IRQ code to seperate file
 */
 
 #include <linux/init.h>
@@ -57,745 +26,23 @@
 #include <linux/ptrace.h>
 #include <linux/sysdev.h>
 
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/io.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
 
-#include <asm/mach/irq.h>
-
-#include <asm/arch/regs-irq.h>
-#include <asm/arch/regs-gpio.h>
-
-#include "cpu.h"
-#include "pm.h"
-#include "irq.h"
-
-/* wakeup irq control */
-
-#ifdef CONFIG_PM
-
-/* state for IRQs over sleep */
-
-/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
- *
- * set bit to 1 in allow bitfield to enable the wakeup settings on it
-*/
-
-unsigned long s3c_irqwake_intallow	= 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
-unsigned long s3c_irqwake_intmask	= 0xffffffffL;
-unsigned long s3c_irqwake_eintallow	= 0x0000fff0L;
-unsigned long s3c_irqwake_eintmask	= 0xffffffffL;
-
-int
-s3c_irq_wake(unsigned int irqno, unsigned int state)
+static int s3c2410_irq_add(struct sys_device *sysdev)
 {
-	unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
-
-	if (!(s3c_irqwake_intallow & irqbit))
-		return -ENOENT;
-
-	printk(KERN_INFO "wake %s for irq %d\n",
-	       state ? "enabled" : "disabled", irqno);
-
-	if (!state)
-		s3c_irqwake_intmask |= irqbit;
-	else
-		s3c_irqwake_intmask &= ~irqbit;
-
 	return 0;
 }
 
-static int
-s3c_irqext_wake(unsigned int irqno, unsigned int state)
-{
-	unsigned long bit = 1L << (irqno - EXTINT_OFF);
-
-	if (!(s3c_irqwake_eintallow & bit))
-		return -ENOENT;
-
-	printk(KERN_INFO "wake %s for irq %d\n",
-	       state ? "enabled" : "disabled", irqno);
-
-	if (!state)
-		s3c_irqwake_eintmask |= bit;
-	else
-		s3c_irqwake_eintmask &= ~bit;
-
-	return 0;
-}
-
-#else
-#define s3c_irqext_wake NULL
-#define s3c_irq_wake NULL
-#endif
-
-
-static void
-s3c_irq_mask(unsigned int irqno)
-{
-	unsigned long mask;
-
-	irqno -= IRQ_EINT0;
-
-	mask = __raw_readl(S3C2410_INTMSK);
-	mask |= 1UL << irqno;
-	__raw_writel(mask, S3C2410_INTMSK);
-}
-
-static inline void
-s3c_irq_ack(unsigned int irqno)
-{
-	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
-
-	__raw_writel(bitval, S3C2410_SRCPND);
-	__raw_writel(bitval, S3C2410_INTPND);
-}
-
-static inline void
-s3c_irq_maskack(unsigned int irqno)
-{
-	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
-	unsigned long mask;
-
-	mask = __raw_readl(S3C2410_INTMSK);
-	__raw_writel(mask|bitval, S3C2410_INTMSK);
-
-	__raw_writel(bitval, S3C2410_SRCPND);
-	__raw_writel(bitval, S3C2410_INTPND);
-}
-
-
-static void
-s3c_irq_unmask(unsigned int irqno)
-{
-	unsigned long mask;
-
-	if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
-		irqdbf2("s3c_irq_unmask %d\n", irqno);
-
-	irqno -= IRQ_EINT0;
-
-	mask = __raw_readl(S3C2410_INTMSK);
-	mask &= ~(1UL << irqno);
-	__raw_writel(mask, S3C2410_INTMSK);
-}
-
-struct irq_chip s3c_irq_level_chip = {
-	.name		= "s3c-level",
-	.ack		= s3c_irq_maskack,
-	.mask		= s3c_irq_mask,
-	.unmask		= s3c_irq_unmask,
-	.set_wake	= s3c_irq_wake
+static struct sysdev_driver s3c2410_irq_driver = {
+	.add		= s3c2410_irq_add,
+	.suspend	= s3c24xx_irq_suspend,
+	.resume		= s3c24xx_irq_resume,
 };
 
-static struct irq_chip s3c_irq_chip = {
-	.name		= "s3c",
-	.ack		= s3c_irq_ack,
-	.mask		= s3c_irq_mask,
-	.unmask		= s3c_irq_unmask,
-	.set_wake	= s3c_irq_wake
-};
-
-static void
-s3c_irqext_mask(unsigned int irqno)
+static int s3c2410_irq_init(void)
 {
-	unsigned long mask;
-
-	irqno -= EXTINT_OFF;
-
-	mask = __raw_readl(S3C24XX_EINTMASK);
-	mask |= ( 1UL << irqno);
-	__raw_writel(mask, S3C24XX_EINTMASK);
+	return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver);
 }
 
-static void
-s3c_irqext_ack(unsigned int irqno)
-{
-	unsigned long req;
-	unsigned long bit;
-	unsigned long mask;
-
-	bit = 1UL << (irqno - EXTINT_OFF);
-
-	mask = __raw_readl(S3C24XX_EINTMASK);
-
-	__raw_writel(bit, S3C24XX_EINTPEND);
-
-	req = __raw_readl(S3C24XX_EINTPEND);
-	req &= ~mask;
-
-	/* not sure if we should be acking the parent irq... */
-
-	if (irqno <= IRQ_EINT7 ) {
-		if ((req & 0xf0) == 0)
-			s3c_irq_ack(IRQ_EINT4t7);
-	} else {
-		if ((req >> 8) == 0)
-			s3c_irq_ack(IRQ_EINT8t23);
-	}
-}
-
-static void
-s3c_irqext_unmask(unsigned int irqno)
-{
-	unsigned long mask;
-
-	irqno -= EXTINT_OFF;
-
-	mask = __raw_readl(S3C24XX_EINTMASK);
-	mask &= ~( 1UL << irqno);
-	__raw_writel(mask, S3C24XX_EINTMASK);
-}
-
-int
-s3c_irqext_type(unsigned int irq, unsigned int type)
-{
-	void __iomem *extint_reg;
-	void __iomem *gpcon_reg;
-	unsigned long gpcon_offset, extint_offset;
-	unsigned long newvalue = 0, value;
-
-	if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
-	{
-		gpcon_reg = S3C2410_GPFCON;
-		extint_reg = S3C24XX_EXTINT0;
-		gpcon_offset = (irq - IRQ_EINT0) * 2;
-		extint_offset = (irq - IRQ_EINT0) * 4;
-	}
-	else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
-	{
-		gpcon_reg = S3C2410_GPFCON;
-		extint_reg = S3C24XX_EXTINT0;
-		gpcon_offset = (irq - (EXTINT_OFF)) * 2;
-		extint_offset = (irq - (EXTINT_OFF)) * 4;
-	}
-	else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
-	{
-		gpcon_reg = S3C2410_GPGCON;
-		extint_reg = S3C24XX_EXTINT1;
-		gpcon_offset = (irq - IRQ_EINT8) * 2;
-		extint_offset = (irq - IRQ_EINT8) * 4;
-	}
-	else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
-	{
-		gpcon_reg = S3C2410_GPGCON;
-		extint_reg = S3C24XX_EXTINT2;
-		gpcon_offset = (irq - IRQ_EINT8) * 2;
-		extint_offset = (irq - IRQ_EINT16) * 4;
-	} else
-		return -1;
-
-	/* Set the GPIO to external interrupt mode */
-	value = __raw_readl(gpcon_reg);
-	value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
-	__raw_writel(value, gpcon_reg);
-
-	/* Set the external interrupt to pointed trigger type */
-	switch (type)
-	{
-		case IRQT_NOEDGE:
-			printk(KERN_WARNING "No edge setting!\n");
-			break;
-
-		case IRQT_RISING:
-			newvalue = S3C2410_EXTINT_RISEEDGE;
-			break;
-
-		case IRQT_FALLING:
-			newvalue = S3C2410_EXTINT_FALLEDGE;
-			break;
-
-		case IRQT_BOTHEDGE:
-			newvalue = S3C2410_EXTINT_BOTHEDGE;
-			break;
-
-		case IRQT_LOW:
-			newvalue = S3C2410_EXTINT_LOWLEV;
-			break;
-
-		case IRQT_HIGH:
-			newvalue = S3C2410_EXTINT_HILEV;
-			break;
-
-		default:
-			printk(KERN_ERR "No such irq type %d", type);
-			return -1;
-	}
-
-	value = __raw_readl(extint_reg);
-	value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
-	__raw_writel(value, extint_reg);
-
-	return 0;
-}
-
-static struct irq_chip s3c_irqext_chip = {
-	.name		= "s3c-ext",
-	.mask		= s3c_irqext_mask,
-	.unmask		= s3c_irqext_unmask,
-	.ack		= s3c_irqext_ack,
-	.set_type	= s3c_irqext_type,
-	.set_wake	= s3c_irqext_wake
-};
-
-static struct irq_chip s3c_irq_eint0t4 = {
-	.name		= "s3c-ext0",
-	.ack		= s3c_irq_ack,
-	.mask		= s3c_irq_mask,
-	.unmask		= s3c_irq_unmask,
-	.set_wake	= s3c_irq_wake,
-	.set_type	= s3c_irqext_type,
-};
-
-/* mask values for the parent registers for each of the interrupt types */
-
-#define INTMSK_UART0	 (1UL << (IRQ_UART0 - IRQ_EINT0))
-#define INTMSK_UART1	 (1UL << (IRQ_UART1 - IRQ_EINT0))
-#define INTMSK_UART2	 (1UL << (IRQ_UART2 - IRQ_EINT0))
-#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
-
-
-/* UART0 */
-
-static void
-s3c_irq_uart0_mask(unsigned int irqno)
-{
-	s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
-}
-
-static void
-s3c_irq_uart0_unmask(unsigned int irqno)
-{
-	s3c_irqsub_unmask(irqno, INTMSK_UART0);
-}
-
-static void
-s3c_irq_uart0_ack(unsigned int irqno)
-{
-	s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
-}
-
-static struct irq_chip s3c_irq_uart0 = {
-	.name		= "s3c-uart0",
-	.mask		= s3c_irq_uart0_mask,
-	.unmask		= s3c_irq_uart0_unmask,
-	.ack		= s3c_irq_uart0_ack,
-};
-
-/* UART1 */
-
-static void
-s3c_irq_uart1_mask(unsigned int irqno)
-{
-	s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
-}
-
-static void
-s3c_irq_uart1_unmask(unsigned int irqno)
-{
-	s3c_irqsub_unmask(irqno, INTMSK_UART1);
-}
-
-static void
-s3c_irq_uart1_ack(unsigned int irqno)
-{
-	s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
-}
-
-static struct irq_chip s3c_irq_uart1 = {
-	.name		= "s3c-uart1",
-	.mask		= s3c_irq_uart1_mask,
-	.unmask		= s3c_irq_uart1_unmask,
-	.ack		= s3c_irq_uart1_ack,
-};
-
-/* UART2 */
-
-static void
-s3c_irq_uart2_mask(unsigned int irqno)
-{
-	s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
-}
-
-static void
-s3c_irq_uart2_unmask(unsigned int irqno)
-{
-	s3c_irqsub_unmask(irqno, INTMSK_UART2);
-}
-
-static void
-s3c_irq_uart2_ack(unsigned int irqno)
-{
-	s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
-}
-
-static struct irq_chip s3c_irq_uart2 = {
-	.name		= "s3c-uart2",
-	.mask		= s3c_irq_uart2_mask,
-	.unmask		= s3c_irq_uart2_unmask,
-	.ack		= s3c_irq_uart2_ack,
-};
-
-/* ADC and Touchscreen */
-
-static void
-s3c_irq_adc_mask(unsigned int irqno)
-{
-	s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
-}
-
-static void
-s3c_irq_adc_unmask(unsigned int irqno)
-{
-	s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
-}
-
-static void
-s3c_irq_adc_ack(unsigned int irqno)
-{
-	s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
-}
-
-static struct irq_chip s3c_irq_adc = {
-	.name		= "s3c-adc",
-	.mask		= s3c_irq_adc_mask,
-	.unmask		= s3c_irq_adc_unmask,
-	.ack		= s3c_irq_adc_ack,
-};
-
-/* irq demux for adc */
-static void s3c_irq_demux_adc(unsigned int irq,
-			      struct irq_desc *desc)
-{
-	unsigned int subsrc, submsk;
-	unsigned int offset = 9;
-	struct irq_desc *mydesc;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	subsrc &= ~submsk;
-	subsrc >>= offset;
-	subsrc &= 3;
-
-	if (subsrc != 0) {
-		if (subsrc & 1) {
-			mydesc = irq_desc + IRQ_TC;
-			desc_handle_irq(IRQ_TC, mydesc);
-		}
-		if (subsrc & 2) {
-			mydesc = irq_desc + IRQ_ADC;
-			desc_handle_irq(IRQ_ADC, mydesc);
-		}
-	}
-}
-
-static void s3c_irq_demux_uart(unsigned int start)
-{
-	unsigned int subsrc, submsk;
-	unsigned int offset = start - IRQ_S3CUART_RX0;
-	struct irq_desc *desc;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
-		start, offset, subsrc, submsk);
-
-	subsrc &= ~submsk;
-	subsrc >>= offset;
-	subsrc &= 7;
-
-	if (subsrc != 0) {
-		desc = irq_desc + start;
-
-		if (subsrc & 1)
-			desc_handle_irq(start, desc);
-
-		desc++;
-
-		if (subsrc & 2)
-			desc_handle_irq(start+1, desc);
-
-		desc++;
-
-		if (subsrc & 4)
-			desc_handle_irq(start+2, desc);
-	}
-}
-
-/* uart demux entry points */
-
-static void
-s3c_irq_demux_uart0(unsigned int irq,
-		    struct irq_desc *desc)
-{
-	irq = irq;
-	s3c_irq_demux_uart(IRQ_S3CUART_RX0);
-}
-
-static void
-s3c_irq_demux_uart1(unsigned int irq,
-		    struct irq_desc *desc)
-{
-	irq = irq;
-	s3c_irq_demux_uart(IRQ_S3CUART_RX1);
-}
-
-static void
-s3c_irq_demux_uart2(unsigned int irq,
-		    struct irq_desc *desc)
-{
-	irq = irq;
-	s3c_irq_demux_uart(IRQ_S3CUART_RX2);
-}
-
-static void
-s3c_irq_demux_extint8(unsigned int irq,
-		      struct irq_desc *desc)
-{
-	unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
-	unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
-
-	eintpnd &= ~eintmsk;
-	eintpnd &= ~0xff;	/* ignore lower irqs */
-
-	/* we may as well handle all the pending IRQs here */
-
-	while (eintpnd) {
-		irq = __ffs(eintpnd);
-		eintpnd &= ~(1<<irq);
-
-		irq += (IRQ_EINT4 - 4);
-		desc_handle_irq(irq, irq_desc + irq);
-	}
-
-}
-
-static void
-s3c_irq_demux_extint4t7(unsigned int irq,
-			struct irq_desc *desc)
-{
-	unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
-	unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
-
-	eintpnd &= ~eintmsk;
-	eintpnd &= 0xff;	/* only lower irqs */
-
-	/* we may as well handle all the pending IRQs here */
-
-	while (eintpnd) {
-		irq = __ffs(eintpnd);
-		eintpnd &= ~(1<<irq);
-
-		irq += (IRQ_EINT4 - 4);
-
-		desc_handle_irq(irq, irq_desc + irq);
-	}
-}
-
-#ifdef CONFIG_PM
-
-static struct sleep_save irq_save[] = {
-	SAVE_ITEM(S3C2410_INTMSK),
-	SAVE_ITEM(S3C2410_INTSUBMSK),
-};
-
-/* the extint values move between the s3c2410/s3c2440 and the s3c2412
- * so we use an array to hold them, and to calculate the address of
- * the register at run-time
-*/
-
-static unsigned long save_extint[3];
-static unsigned long save_eintflt[4];
-static unsigned long save_eintmask;
-
-int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
-		save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
-
-	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
-		save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
-
-	s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
-	save_eintmask = __raw_readl(S3C24XX_EINTMASK);
-
-	return 0;
-}
-
-int s3c24xx_irq_resume(struct sys_device *dev)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
-		__raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
-
-	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
-		__raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
-
-	s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
-	__raw_writel(save_eintmask, S3C24XX_EINTMASK);
-
-	return 0;
-}
-
-#else
-#define s3c24xx_irq_suspend NULL
-#define s3c24xx_irq_resume  NULL
-#endif
-
-/* s3c24xx_init_irq
- *
- * Initialise S3C2410 IRQ system
-*/
-
-void __init s3c24xx_init_irq(void)
-{
-	unsigned long pend;
-	unsigned long last;
-	int irqno;
-	int i;
-
-	irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
-
-	/* first, clear all interrupts pending... */
-
-	last = 0;
-	for (i = 0; i < 4; i++) {
-		pend = __raw_readl(S3C24XX_EINTPEND);
-
-		if (pend == 0 || pend == last)
-			break;
-
-		__raw_writel(pend, S3C24XX_EINTPEND);
-		printk("irq: clearing pending ext status %08x\n", (int)pend);
-		last = pend;
-	}
-
-	last = 0;
-	for (i = 0; i < 4; i++) {
-		pend = __raw_readl(S3C2410_INTPND);
-
-		if (pend == 0 || pend == last)
-			break;
-
-		__raw_writel(pend, S3C2410_SRCPND);
-		__raw_writel(pend, S3C2410_INTPND);
-		printk("irq: clearing pending status %08x\n", (int)pend);
-		last = pend;
-	}
-
-	last = 0;
-	for (i = 0; i < 4; i++) {
-		pend = __raw_readl(S3C2410_SUBSRCPND);
-
-		if (pend == 0 || pend == last)
-			break;
-
-		printk("irq: clearing subpending status %08x\n", (int)pend);
-		__raw_writel(pend, S3C2410_SUBSRCPND);
-		last = pend;
-	}
-
-	/* register the main interrupts */
-
-	irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
-
-	for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
-		/* set all the s3c2410 internal irqs */
-
-		switch (irqno) {
-			/* deal with the special IRQs (cascaded) */
-
-		case IRQ_EINT4t7:
-		case IRQ_EINT8t23:
-		case IRQ_UART0:
-		case IRQ_UART1:
-		case IRQ_UART2:
-		case IRQ_ADCPARENT:
-			set_irq_chip(irqno, &s3c_irq_level_chip);
-			set_irq_handler(irqno, handle_level_irq);
-			break;
-
-		case IRQ_RESERVED6:
-		case IRQ_RESERVED24:
-			/* no IRQ here */
-			break;
-
-		default:
-			//irqdbf("registering irq %d (s3c irq)\n", irqno);
-			set_irq_chip(irqno, &s3c_irq_chip);
-			set_irq_handler(irqno, handle_edge_irq);
-			set_irq_flags(irqno, IRQF_VALID);
-		}
-	}
-
-	/* setup the cascade irq handlers */
-
-	set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
-	set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
-
-	set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
-	set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
-	set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
-	set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
-
-	/* external interrupts */
-
-	for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
-		irqdbf("registering irq %d (ext int)\n", irqno);
-		set_irq_chip(irqno, &s3c_irq_eint0t4);
-		set_irq_handler(irqno, handle_edge_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
-		irqdbf("registering irq %d (extended s3c irq)\n", irqno);
-		set_irq_chip(irqno, &s3c_irqext_chip);
-		set_irq_handler(irqno, handle_edge_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	/* register the uart interrupts */
-
-	irqdbf("s3c2410: registering external interrupts\n");
-
-	for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
-		irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
-		set_irq_chip(irqno, &s3c_irq_uart0);
-		set_irq_handler(irqno, handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
-		irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
-		set_irq_chip(irqno, &s3c_irq_uart1);
-		set_irq_handler(irqno, handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
-		irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
-		set_irq_chip(irqno, &s3c_irq_uart2);
-		set_irq_handler(irqno, handle_level_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
-		irqdbf("registering irq %d (s3c adc irq)\n", irqno);
-		set_irq_chip(irqno, &s3c_irq_adc);
-		set_irq_handler(irqno, handle_edge_irq);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	irqdbf("s3c2410: registered interrupt handlers\n");
-}
+arch_initcall(s3c2410_irq_init);
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index 817e2c6..72f2cc4 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -1,4 +1,4 @@
-/***********************************************************************
+/* linux/arch/arm/mach-s3c2410/mach-amlm5900.c
  *
  * linux/arch/arm/mach-s3c2410/mach-amlm5900.c
  *
@@ -35,7 +35,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/proc_fs.h>
-
+#include <linux/serial_core.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -52,8 +52,8 @@
 #include <asm/arch/regs-lcd.h>
 #include <asm/arch/regs-gpio.h>
 
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 #ifdef CONFIG_MTD_PARTITIONS
 
@@ -113,12 +113,6 @@
 #endif
 
 static struct map_desc amlm5900_iodesc[] __initdata = {
-	{
-		.virtual	= (u32)S3C24XX_VA_SPI,
-		.pfn		= __phys_to_pfn(S3C2410_PA_SPI),
-		.length		= SZ_1M,
-		.type		= MT_DEVICE
-	}
 };
 
 #define UCON S3C2410_UCON_DEFAULT
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index b8b7675..7b81296 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -50,9 +50,9 @@
 
 #include <linux/serial_8250.h>
 
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 #include "usb-simtec.h"
 
 #define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 15b625e..01c60d0 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -25,23 +25,24 @@
 #include <asm/mach/irq.h>
 
 #include <asm/hardware.h>
-#include <asm/hardware/iomd.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-
 #include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-clock.h>
 
 #include <asm/arch/h1940.h>
 #include <asm/arch/h1940-latch.h>
 #include <asm/arch/fb.h>
+#include <asm/arch/udc.h>
 
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
-#include "pm.h"
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
 
 static struct map_desc h1940_iodesc[] __initdata = {
 	[0] = {
@@ -102,6 +103,32 @@
 
 EXPORT_SYMBOL_GPL(h1940_latch_control);
 
+static void h1940_udc_pullup(enum s3c2410_udc_cmd_e cmd)
+{
+	printk(KERN_DEBUG "udc: pullup(%d)\n",cmd);
+
+	switch (cmd)
+	{
+		case S3C2410_UDC_P_ENABLE :
+			h1940_latch_control(0, H1940_LATCH_USB_DP);
+			break;
+		case S3C2410_UDC_P_DISABLE :
+			h1940_latch_control(H1940_LATCH_USB_DP, 0);
+			break;
+		case S3C2410_UDC_P_RESET :
+			break;
+		default:
+			break;
+	}
+}
+
+static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
+	.udc_command		= h1940_udc_pullup,
+	.vbus_pin		= S3C2410_GPG5,
+	.vbus_pin_inverted	= 1,
+};
+
+
 
 /**
  * Set lcd on or off
@@ -146,12 +173,19 @@
 	.bpp=		{16,16,16},
 };
 
+static struct platform_device s3c_device_leds = {
+	.name             = "h1940-leds",
+	.id               = -1,
+};
+
 static struct platform_device *h1940_devices[] __initdata = {
 	&s3c_device_usb,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c,
 	&s3c_device_iis,
+	&s3c_device_usbgadget,
+	&s3c_device_leds,
 };
 
 static struct s3c24xx_board h1940_board __initdata = {
@@ -179,7 +213,23 @@
 
 static void __init h1940_init(void)
 {
+	u32 tmp;
+
 	s3c24xx_fb_set_platdata(&h1940_lcdcfg);
+ 	s3c24xx_udc_set_platdata(&h1940_udc_cfg);
+
+	/* Turn off suspend on both USB ports, and switch the
+	 * selectable USB port to USB device mode. */
+
+	s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+			      S3C2410_MISCCR_USBSUSPND0 |
+			      S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+	tmp = (
+		 0x78 << S3C2410_PLLCON_MDIVSHIFT)
+	      | (0x02 << S3C2410_PLLCON_PDIVSHIFT)
+	      | (0x03 << S3C2410_PLLCON_SDIVSHIFT);
+	writel(tmp, S3C2410_UPLLCON);
 }
 
 MACHINE_START(H1940, "IPAQ-H1940")
@@ -189,6 +239,6 @@
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= h1940_map_io,
 	.init_irq	= h1940_init_irq,
-	.init_machine   = h1940_init,
+	.init_machine	= h1940_init,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 0411e9a..261aa4c 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -29,7 +29,6 @@
 #include <asm/mach/irq.h>
 
 #include <asm/hardware.h>
-#include <asm/hardware/iomd.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
@@ -38,10 +37,10 @@
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/iic.h>
 
-#include "s3c2410.h"
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 static struct map_desc n30_iodesc[] __initdata = {
 	/* nothing here yet */
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
index 2c738b3..c78ab75 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -32,10 +32,10 @@
 #include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 
-#include "s3c2410.h"
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 static struct map_desc otom11_iodesc[] __initdata = {
   /* Device area */
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
new file mode 100644
index 0000000..c6a4159
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -0,0 +1,448 @@
+/* linux/arch/arm/mach-s3c2410/mach-qt2410.c
+ *
+ * Copyright (C) 2006 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/mmc/protocol.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/leds-gpio.h>
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/fb.h>
+#include <asm/arch/nand.h>
+#include <asm/arch/udc.h>
+#include <asm/arch/spi.h>
+#include <asm/arch/spi-gpio.h>
+
+#include <asm/plat-s3c24xx/common-smdk.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+
+static struct map_desc qt2410_iodesc[] __initdata = {
+	{ 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE }
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	[2] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	}
+};
+
+/* LCD driver info */
+
+/* Configuration for 640x480 SHARP LQ080V3DG01 */
+static struct s3c2410fb_mach_info qt2410_biglcd_cfg __initdata = {
+	.regs	= {
+
+		.lcdcon1	= S3C2410_LCDCON1_TFT16BPP |
+				  S3C2410_LCDCON1_TFT |
+				  S3C2410_LCDCON1_CLKVAL(0x01),	/* HCLK/4 */
+
+		.lcdcon2	= S3C2410_LCDCON2_VBPD(18) |	/* 19 */
+				  S3C2410_LCDCON2_LINEVAL(479) |
+				  S3C2410_LCDCON2_VFPD(10) |	/* 11 */
+				  S3C2410_LCDCON2_VSPW(14),	/* 15 */
+
+		.lcdcon3	= S3C2410_LCDCON3_HBPD(43) |	/* 44 */
+				  S3C2410_LCDCON3_HOZVAL(639) |	/* 640 */
+				  S3C2410_LCDCON3_HFPD(115),	/* 116 */
+
+		.lcdcon4	= S3C2410_LCDCON4_MVAL(0) |
+				  S3C2410_LCDCON4_HSPW(95),	/* 96 */
+
+		.lcdcon5	= S3C2410_LCDCON5_FRM565 |
+				  S3C2410_LCDCON5_INVVLINE |
+				  S3C2410_LCDCON5_INVVFRAME |
+				  S3C2410_LCDCON5_PWREN |
+				  S3C2410_LCDCON5_HWSWP,
+	},
+
+	.lpcsel		= ((0xCE6) & ~7) | 1<<4,
+
+	.width		= 640,
+	.height		= 480,
+
+	.xres		= {
+		.min	= 640,
+		.max	= 640,
+		.defval	= 640,
+	},
+
+	.yres		= {
+		.min	= 480,
+		.max	= 480,
+		.defval = 480,
+	},
+
+	.bpp		= {
+		.min	= 16,
+		.max	= 16,
+		.defval = 16,
+	},
+};
+
+/* Configuration for 480x640 toppoly TD028TTEC1 */
+static struct s3c2410fb_mach_info qt2410_prodlcd_cfg __initdata = {
+	.regs	= {
+
+		.lcdcon1	= S3C2410_LCDCON1_TFT16BPP |
+				  S3C2410_LCDCON1_TFT |
+				  S3C2410_LCDCON1_CLKVAL(0x01),	/* HCLK/4 */
+
+		.lcdcon2	= S3C2410_LCDCON2_VBPD(1) |	/* 2 */
+				  S3C2410_LCDCON2_LINEVAL(639) |/* 640 */
+				  S3C2410_LCDCON2_VFPD(3) |	/* 4 */
+				  S3C2410_LCDCON2_VSPW(1),	/* 2 */
+
+		.lcdcon3	= S3C2410_LCDCON3_HBPD(7) |	/* 8 */
+				  S3C2410_LCDCON3_HOZVAL(479) |	/* 479 */
+				  S3C2410_LCDCON3_HFPD(23),	/* 24 */
+
+		.lcdcon4	= S3C2410_LCDCON4_MVAL(0) |
+				  S3C2410_LCDCON4_HSPW(7),	/* 8 */
+
+		.lcdcon5	= S3C2410_LCDCON5_FRM565 |
+				  S3C2410_LCDCON5_INVVLINE |
+				  S3C2410_LCDCON5_INVVFRAME |
+				  S3C2410_LCDCON5_PWREN |
+				  S3C2410_LCDCON5_HWSWP,
+	},
+
+	.lpcsel		= ((0xCE6) & ~7) | 1<<4,
+
+	.width		= 480,
+	.height		= 640,
+
+	.xres		= {
+		.min	= 480,
+		.max	= 480,
+		.defval	= 480,
+	},
+
+	.yres		= {
+		.min	= 640,
+		.max	= 640,
+		.defval = 640,
+	},
+
+	.bpp		= {
+		.min	= 16,
+		.max	= 16,
+		.defval = 16,
+	},
+};
+
+/* Config for 240x320 LCD */
+static struct s3c2410fb_mach_info qt2410_lcd_cfg __initdata = {
+	.regs	= {
+
+		.lcdcon1	= S3C2410_LCDCON1_TFT16BPP |
+				  S3C2410_LCDCON1_TFT |
+				  S3C2410_LCDCON1_CLKVAL(0x04),
+
+		.lcdcon2	= S3C2410_LCDCON2_VBPD(1) |
+				  S3C2410_LCDCON2_LINEVAL(319) |
+				  S3C2410_LCDCON2_VFPD(6) |
+				  S3C2410_LCDCON2_VSPW(3),
+
+		.lcdcon3	= S3C2410_LCDCON3_HBPD(12) |
+				  S3C2410_LCDCON3_HOZVAL(239) |
+				  S3C2410_LCDCON3_HFPD(7),
+
+		.lcdcon4	= S3C2410_LCDCON4_MVAL(0) |
+				  S3C2410_LCDCON4_HSPW(3),
+
+		.lcdcon5	= S3C2410_LCDCON5_FRM565 |
+				  S3C2410_LCDCON5_INVVLINE |
+				  S3C2410_LCDCON5_INVVFRAME |
+				  S3C2410_LCDCON5_PWREN |
+				  S3C2410_LCDCON5_HWSWP,
+	},
+
+	.lpcsel		= ((0xCE6) & ~7) | 1<<4,
+
+	.width		= 240,
+	.height		= 320,
+
+	.xres		= {
+		.min	= 240,
+		.max	= 240,
+		.defval	= 240,
+	},
+
+	.yres		= {
+		.min	= 320,
+		.max	= 320,
+		.defval = 320,
+	},
+
+	.bpp		= {
+		.min	= 16,
+		.max	= 16,
+		.defval = 16,
+	},
+};
+
+/* CS8900 */
+
+static struct resource qt2410_cs89x0_resources[] = {
+	[0] = {
+		.start	= 0x19000000,
+		.end	= 0x19000000 + 16,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_EINT9,
+		.end	= IRQ_EINT9,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device qt2410_cs89x0 = {
+	.name		= "cirrus-cs89x0",
+	.num_resources	= ARRAY_SIZE(qt2410_cs89x0_resources),
+	.resource	= qt2410_cs89x0_resources,
+};
+
+/* LED */
+
+static struct s3c24xx_led_platdata qt2410_pdata_led = {
+	.gpio		= S3C2410_GPB0,
+	.flags		= S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+	.name		= "led",
+	.def_trigger	= "timer",
+};
+
+static struct platform_device qt2410_led = {
+	.name		= "s3c24xx_led",
+	.id		= 0,
+	.dev		= {
+		.platform_data = &qt2410_pdata_led,
+	},
+};
+
+/* SPI */
+
+static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int cs)
+{
+	switch (cs) {
+	case BITBANG_CS_ACTIVE:
+		s3c2410_gpio_setpin(S3C2410_GPB5, 0);
+		break;
+	case BITBANG_CS_INACTIVE:
+		s3c2410_gpio_setpin(S3C2410_GPB5, 1);
+		break;
+	}
+}
+
+static struct s3c2410_spigpio_info spi_gpio_cfg = {
+	.pin_clk	= S3C2410_GPG7,
+	.pin_mosi	= S3C2410_GPG6,
+	.pin_miso	= S3C2410_GPG5,
+	.chip_select	= &spi_gpio_cs,
+};
+
+
+static struct platform_device qt2410_spi = {
+	.name		  = "s3c24xx-spi-gpio",
+	.id		  = 1,
+	.dev = {
+		.platform_data = &spi_gpio_cfg,
+	},
+};
+
+/* Board devices */
+
+static struct platform_device *qt2410_devices[] __initdata = {
+	&s3c_device_usb,
+	&s3c_device_lcd,
+	&s3c_device_wdt,
+	&s3c_device_i2c,
+	&s3c_device_iis,
+	&s3c_device_sdi,
+	&s3c_device_usbgadget,
+	&qt2410_spi,
+	&qt2410_cs89x0,
+	&qt2410_led,
+};
+
+static struct s3c24xx_board qt2410_board __initdata = {
+	.devices       = qt2410_devices,
+	.devices_count = ARRAY_SIZE(qt2410_devices)
+};
+
+static struct mtd_partition qt2410_nand_part[] = {
+	[0] = {
+		.name	= "U-Boot",
+		.size	= 0x30000,
+		.offset	= 0,
+	},
+	[1] = {
+		.name	= "U-Boot environment",
+		.offset = 0x30000,
+		.size	= 0x4000,
+	},
+	[2] = {
+		.name	= "kernel",
+		.offset = 0x34000,
+		.size	= SZ_2M,
+	},
+	[3] = {
+		.name	= "initrd",
+		.offset	= 0x234000,
+		.size	= SZ_4M,
+	},
+	[4] = {
+		.name	= "jffs2",
+		.offset = 0x634000,
+		.size	= 0x39cc000,
+	},
+};
+
+static struct s3c2410_nand_set qt2410_nand_sets[] = {
+	[0] = {
+		.name		= "NAND",
+		.nr_chips	= 1,
+		.nr_partitions	= ARRAY_SIZE(qt2410_nand_part),
+		.partitions	= qt2410_nand_part,
+	},
+};
+
+/* choose a set of timings which should suit most 512Mbit
+ * chips and beyond.
+ */
+
+static struct s3c2410_platform_nand qt2410_nand_info = {
+	.tacls		= 20,
+	.twrph0		= 60,
+	.twrph1		= 20,
+	.nr_sets	= ARRAY_SIZE(qt2410_nand_sets),
+	.sets		= qt2410_nand_sets,
+};
+
+/* UDC */
+
+static struct s3c2410_udc_mach_info qt2410_udc_cfg = {
+};
+
+static char tft_type = 's';
+
+static int __init qt2410_tft_setup(char *str)
+{
+	tft_type = str[0];
+	return 1;
+}
+
+__setup("tft=", qt2410_tft_setup);
+
+static void __init qt2410_map_io(void)
+{
+	s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
+	s3c24xx_init_clocks(12*1000*1000);
+	s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
+	s3c24xx_set_board(&qt2410_board);
+}
+
+static void __init qt2410_machine_init(void)
+{
+	s3c_device_nand.dev.platform_data = &qt2410_nand_info;
+
+	switch (tft_type) {
+	case 'p': /* production */
+		s3c24xx_fb_set_platdata(&qt2410_prodlcd_cfg);
+		break;
+	case 'b': /* big */
+		s3c24xx_fb_set_platdata(&qt2410_biglcd_cfg);
+		break;
+	case 's': /* small */
+	default:
+		s3c24xx_fb_set_platdata(&qt2410_lcd_cfg);
+		break;
+	}
+
+	s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPIO_OUTPUT);
+	s3c2410_gpio_setpin(S3C2410_GPB0, 1);
+
+	s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
+
+	s3c2410_gpio_cfgpin(S3C2410_GPB5, S3C2410_GPIO_OUTPUT);
+
+	s3c2410_pm_init();
+}
+
+MACHINE_START(QT2410, "QT2410")
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+	.map_io		= qt2410_map_io,
+	.init_irq	= s3c24xx_init_irq,
+	.init_machine	= qt2410_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
+
+
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index 01c0c98..57b8a80 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -1,4 +1,4 @@
-/***********************************************************************
+/* linux/arch/arm/mach-s3c2410/mach-smdk2410.c
  *
  * linux/arch/arm/mach-s3c2410/mach-smdk2410.c
  *
@@ -49,10 +49,10 @@
 
 #include <asm/arch/regs-serial.h>
 
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
-#include "common-smdk.h"
+#include <asm/plat-s3c24xx/common-smdk.h>
 
 static struct map_desc smdk2410_iodesc[] __initdata = {
   /* nothing here yet */
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index a382fc0..c947c75 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -43,9 +43,9 @@
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/leds-gpio.h>
 
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 #include "usb-simtec.h"
 
 /* macros for virtual address mods for the io space entries */
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
index ebf294d..3b3a7db 100644
--- a/arch/arm/mach-s3c2410/pm.c
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -1,11 +1,9 @@
 /* linux/arch/arm/mach-s3c2410/pm.c
  *
- * Copyright (c) 2004,2006 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
- * S3C24XX Power Manager (Suspend-To-RAM) support
- *
- * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information
+ * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
  *
  * 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
@@ -20,640 +18,139 @@
  * 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
- *
- * Parts based on arch/arm/mach-pxa/pm.c
- *
- * Thanks to Dimitry Andric for debugging
 */
 
 #include <linux/init.h>
 #include <linux/suspend.h>
 #include <linux/errno.h>
 #include <linux/time.h>
-#include <linux/interrupt.h>
-#include <linux/crc32.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/serial_core.h>
+#include <linux/sysdev.h>
 
-#include <asm/cacheflush.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-clock.h>
+#include <asm/mach-types.h>
+
 #include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-mem.h>
-#include <asm/arch/regs-irq.h>
+#include <asm/arch/h1940.h>
 
-#include <asm/mach/time.h>
-
-#include "pm.h"
-
-/* for external use */
-
-unsigned long s3c_pm_flags;
-
-#define PFX "s3c24xx-pm: "
-
-static struct sleep_save core_save[] = {
-	SAVE_ITEM(S3C2410_LOCKTIME),
-	SAVE_ITEM(S3C2410_CLKCON),
-
-	/* we restore the timings here, with the proviso that the board
-	 * brings the system up in an slower, or equal frequency setting
-	 * to the original system.
-	 *
-	 * if we cannot guarantee this, then things are going to go very
-	 * wrong here, as we modify the refresh and both pll settings.
-	 */
-
-	SAVE_ITEM(S3C2410_BWSCON),
-	SAVE_ITEM(S3C2410_BANKCON0),
-	SAVE_ITEM(S3C2410_BANKCON1),
-	SAVE_ITEM(S3C2410_BANKCON2),
-	SAVE_ITEM(S3C2410_BANKCON3),
-	SAVE_ITEM(S3C2410_BANKCON4),
-	SAVE_ITEM(S3C2410_BANKCON5),
-
-	SAVE_ITEM(S3C2410_CLKDIVN),
-	SAVE_ITEM(S3C2410_MPLLCON),
-	SAVE_ITEM(S3C2410_UPLLCON),
-	SAVE_ITEM(S3C2410_CLKSLOW),
-	SAVE_ITEM(S3C2410_REFRESH),
-};
-
-static struct sleep_save gpio_save[] = {
-	SAVE_ITEM(S3C2410_GPACON),
-	SAVE_ITEM(S3C2410_GPADAT),
-
-	SAVE_ITEM(S3C2410_GPBCON),
-	SAVE_ITEM(S3C2410_GPBDAT),
-	SAVE_ITEM(S3C2410_GPBUP),
-
-	SAVE_ITEM(S3C2410_GPCCON),
-	SAVE_ITEM(S3C2410_GPCDAT),
-	SAVE_ITEM(S3C2410_GPCUP),
-
-	SAVE_ITEM(S3C2410_GPDCON),
-	SAVE_ITEM(S3C2410_GPDDAT),
-	SAVE_ITEM(S3C2410_GPDUP),
-
-	SAVE_ITEM(S3C2410_GPECON),
-	SAVE_ITEM(S3C2410_GPEDAT),
-	SAVE_ITEM(S3C2410_GPEUP),
-
-	SAVE_ITEM(S3C2410_GPFCON),
-	SAVE_ITEM(S3C2410_GPFDAT),
-	SAVE_ITEM(S3C2410_GPFUP),
-
-	SAVE_ITEM(S3C2410_GPGCON),
-	SAVE_ITEM(S3C2410_GPGDAT),
-	SAVE_ITEM(S3C2410_GPGUP),
-
-	SAVE_ITEM(S3C2410_GPHCON),
-	SAVE_ITEM(S3C2410_GPHDAT),
-	SAVE_ITEM(S3C2410_GPHUP),
-
-	SAVE_ITEM(S3C2410_DCLKCON),
-};
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
 
 #ifdef CONFIG_S3C2410_PM_DEBUG
-
-#define SAVE_UART(va) \
-	SAVE_ITEM((va) + S3C2410_ULCON), \
-	SAVE_ITEM((va) + S3C2410_UCON), \
-	SAVE_ITEM((va) + S3C2410_UFCON), \
-	SAVE_ITEM((va) + S3C2410_UMCON), \
-	SAVE_ITEM((va) + S3C2410_UBRDIV)
-
-static struct sleep_save uart_save[] = {
-	SAVE_UART(S3C24XX_VA_UART0),
-	SAVE_UART(S3C24XX_VA_UART1),
-#ifndef CONFIG_CPU_S3C2400
-	SAVE_UART(S3C24XX_VA_UART2),
-#endif
-};
-
-/* debug
- *
- * we send the debug to printascii() to allow it to be seen if the
- * system never wakes up from the sleep
-*/
-
-extern void printascii(const char *);
-
-void pm_dbg(const char *fmt, ...)
-{
-	va_list va;
-	char buff[256];
-
-	va_start(va, fmt);
-	vsprintf(buff, fmt, va);
-	va_end(va);
-
-	printascii(buff);
-}
-
-static void s3c2410_pm_debug_init(void)
-{
-	unsigned long tmp = __raw_readl(S3C2410_CLKCON);
-
-	/* re-start uart clocks */
-	tmp |= S3C2410_CLKCON_UART0;
-	tmp |= S3C2410_CLKCON_UART1;
-	tmp |= S3C2410_CLKCON_UART2;
-
-	__raw_writel(tmp, S3C2410_CLKCON);
-	udelay(10);
-}
-
+extern void pm_dbg(const char *fmt, ...);
 #define DBG(fmt...) pm_dbg(fmt)
 #else
 #define DBG(fmt...) printk(KERN_DEBUG fmt)
-
-#define s3c2410_pm_debug_init() do { } while(0)
-
-static struct sleep_save uart_save[] = {};
 #endif
 
-#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0
-
-/* suspend checking code...
- *
- * this next area does a set of crc checks over all the installed
- * memory, so the system can verify if the resume was ok.
- *
- * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
- * increasing it will mean that the area corrupted will be less easy to spot,
- * and reducing the size will cause the CRC save area to grow
-*/
-
-#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024)
-
-static u32 crc_size;	/* size needed for the crc block */
-static u32 *crcs;	/* allocated over suspend/resume */
-
-typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
-
-/* s3c2410_pm_run_res
- *
- * go thorugh the given resource list, and look for system ram
-*/
-
-static void s3c2410_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
+static void s3c2410_pm_prepare(void)
 {
-	while (ptr != NULL) {
-		if (ptr->child != NULL)
-			s3c2410_pm_run_res(ptr->child, fn, arg);
+	/* ensure at least GSTATUS3 has the resume address */
 
-		if ((ptr->flags & IORESOURCE_MEM) &&
-		    strcmp(ptr->name, "System RAM") == 0) {
-			DBG("Found system RAM at %08lx..%08lx\n",
-			    ptr->start, ptr->end);
-			arg = (fn)(ptr, arg);
-		}
+	__raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
 
-		ptr = ptr->sibling;
-	}
-}
+	DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
+	DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
 
-static void s3c2410_pm_run_sysram(run_fn_t fn, u32 *arg)
-{
-	s3c2410_pm_run_res(&iomem_resource, fn, arg);
-}
+	if (machine_is_h1940()) {
+		void *base = phys_to_virt(H1940_SUSPEND_CHECK);
+		unsigned long ptr;
+		unsigned long calc = 0;
 
-static u32 *s3c2410_pm_countram(struct resource *res, u32 *val)
-{
-	u32 size = (u32)(res->end - res->start)+1;
+		/* generate check for the bootloader to check on resume */
 
-	size += CHECK_CHUNKSIZE-1;
-	size /= CHECK_CHUNKSIZE;
+		for (ptr = 0; ptr < 0x40000; ptr += 0x400)
+			calc += __raw_readl(base+ptr);
 
-	DBG("Area %08lx..%08lx, %d blocks\n", res->start, res->end, size);
-
-	*val += size * sizeof(u32);
-	return val;
-}
-
-/* s3c2410_pm_prepare_check
- *
- * prepare the necessary information for creating the CRCs. This
- * must be done before the final save, as it will require memory
- * allocating, and thus touching bits of the kernel we do not
- * know about.
-*/
-
-static void s3c2410_pm_check_prepare(void)
-{
-	crc_size = 0;
-
-	s3c2410_pm_run_sysram(s3c2410_pm_countram, &crc_size);
-
-	DBG("s3c2410_pm_prepare_check: %u checks needed\n", crc_size);
-
-	crcs = kmalloc(crc_size+4, GFP_KERNEL);
-	if (crcs == NULL)
-		printk(KERN_ERR "Cannot allocated CRC save area\n");
-}
-
-static u32 *s3c2410_pm_makecheck(struct resource *res, u32 *val)
-{
-	unsigned long addr, left;
-
-	for (addr = res->start; addr < res->end;
-	     addr += CHECK_CHUNKSIZE) {
-		left = res->end - addr;
-
-		if (left > CHECK_CHUNKSIZE)
-			left = CHECK_CHUNKSIZE;
-
-		*val = crc32_le(~0, phys_to_virt(addr), left);
-		val++;
+		__raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
 	}
 
-	return val;
+	/* the RX3715 uses similar code and the same H1940 and the
+	 * same offsets for resume and checksum pointers */
+
+	if (machine_is_rx3715()) {
+		void *base = phys_to_virt(H1940_SUSPEND_CHECK);
+		unsigned long ptr;
+		unsigned long calc = 0;
+
+		/* generate check for the bootloader to check on resume */
+
+		for (ptr = 0; ptr < 0x40000; ptr += 0x4)
+			calc += __raw_readl(base+ptr);
+
+		__raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
+	}
+
+	if ( machine_is_aml_m5900() )
+		s3c2410_gpio_setpin(S3C2410_GPF2, 1);
+
 }
 
-/* s3c2410_pm_check_store
- *
- * compute the CRC values for the memory blocks before the final
- * sleep.
-*/
-
-static void s3c2410_pm_check_store(void)
+static int s3c2410_pm_resume(struct sys_device *dev)
 {
-	if (crcs != NULL)
-		s3c2410_pm_run_sysram(s3c2410_pm_makecheck, crcs);
-}
+	unsigned long tmp;
 
-/* in_region
- *
- * return TRUE if the area defined by ptr..ptr+size contatins the
- * what..what+whatsz
-*/
+	/* unset the return-from-sleep flag, to ensure reset */
 
-static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
-{
-	if ((what+whatsz) < ptr)
-		return 0;
+	tmp = __raw_readl(S3C2410_GSTATUS2);
+	tmp &= S3C2410_GSTATUS2_OFFRESET;
+	__raw_writel(tmp, S3C2410_GSTATUS2);
 
-	if (what > (ptr+size))
-		return 0;
-
-	return 1;
-}
-
-static u32 *s3c2410_pm_runcheck(struct resource *res, u32 *val)
-{
-	void *save_at = phys_to_virt(s3c2410_sleep_save_phys);
-	unsigned long addr;
-	unsigned long left;
-	void *ptr;
-	u32 calc;
-
-	for (addr = res->start; addr < res->end;
-	     addr += CHECK_CHUNKSIZE) {
-		left = res->end - addr;
-
-		if (left > CHECK_CHUNKSIZE)
-			left = CHECK_CHUNKSIZE;
-
-		ptr = phys_to_virt(addr);
-
-		if (in_region(ptr, left, crcs, crc_size)) {
-			DBG("skipping %08lx, has crc block in\n", addr);
-			goto skip_check;
-		}
-
-		if (in_region(ptr, left, save_at, 32*4 )) {
-			DBG("skipping %08lx, has save block in\n", addr);
-			goto skip_check;
-		}
-
-		/* calculate and check the checksum */
-
-		calc = crc32_le(~0, ptr, left);
-		if (calc != *val) {
-			printk(KERN_ERR PFX "Restore CRC error at "
-			       "%08lx (%08x vs %08x)\n", addr, calc, *val);
-
-			DBG("Restore CRC error at %08lx (%08x vs %08x)\n",
-			    addr, calc, *val);
-		}
-
-	skip_check:
-		val++;
-	}
-
-	return val;
-}
-
-/* s3c2410_pm_check_restore
- *
- * check the CRCs after the restore event and free the memory used
- * to hold them
-*/
-
-static void s3c2410_pm_check_restore(void)
-{
-	if (crcs != NULL) {
-		s3c2410_pm_run_sysram(s3c2410_pm_runcheck, crcs);
-		kfree(crcs);
-		crcs = NULL;
-	}
-}
-
-#else
-
-#define s3c2410_pm_check_prepare() do { } while(0)
-#define s3c2410_pm_check_restore() do { } while(0)
-#define s3c2410_pm_check_store()   do { } while(0)
-#endif
-
-/* helper functions to save and restore register state */
-
-void s3c2410_pm_do_save(struct sleep_save *ptr, int count)
-{
-	for (; count > 0; count--, ptr++) {
-		ptr->val = __raw_readl(ptr->reg);
-		DBG("saved %p value %08lx\n", ptr->reg, ptr->val);
-	}
-}
-
-/* s3c2410_pm_do_restore
- *
- * restore the system from the given list of saved registers
- *
- * Note, we do not use DBG() in here, as the system may not have
- * restore the UARTs state yet
-*/
-
-void s3c2410_pm_do_restore(struct sleep_save *ptr, int count)
-{
-	for (; count > 0; count--, ptr++) {
-		printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
-		       ptr->reg, ptr->val, __raw_readl(ptr->reg));
-
-		__raw_writel(ptr->val, ptr->reg);
-	}
-}
-
-/* s3c2410_pm_do_restore_core
- *
- * similar to s3c2410_pm_do_restore_core
- *
- * WARNING: Do not put any debug in here that may effect memory or use
- * peripherals, as things may be changing!
-*/
-
-static void s3c2410_pm_do_restore_core(struct sleep_save *ptr, int count)
-{
-	for (; count > 0; count--, ptr++) {
-		__raw_writel(ptr->val, ptr->reg);
-	}
-}
-
-/* s3c2410_pm_show_resume_irqs
- *
- * print any IRQs asserted at resume time (ie, we woke from)
-*/
-
-static void s3c2410_pm_show_resume_irqs(int start, unsigned long which,
-					unsigned long mask)
-{
-	int i;
-
-	which &= ~mask;
-
-	for (i = 0; i <= 31; i++) {
-		if ((which) & (1L<<i)) {
-			DBG("IRQ %d asserted at resume\n", start+i);
-		}
-	}
-}
-
-/* s3c2410_pm_check_resume_pin
- *
- * check to see if the pin is configured correctly for sleep mode, and
- * make any necessary adjustments if it is not
-*/
-
-static void s3c2410_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
-{
-	unsigned long irqstate;
-	unsigned long pinstate;
-	int irq = s3c2410_gpio_getirq(pin);
-
-	if (irqoffs < 4)
-		irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
-	else
-		irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
-
-	pinstate = s3c2410_gpio_getcfg(pin);
-
-	if (!irqstate) {
-		if (pinstate == S3C2410_GPIO_IRQ)
-			DBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
-	} else {
-		if (pinstate == S3C2410_GPIO_IRQ) {
-			DBG("Disabling IRQ %d (pin %d)\n", irq, pin);
-			s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
-		}
-	}
-}
-
-/* s3c2410_pm_configure_extint
- *
- * configure all external interrupt pins
-*/
-
-static void s3c2410_pm_configure_extint(void)
-{
-	int pin;
-
-	/* for each of the external interrupts (EINT0..EINT15) we
-	 * need to check wether it is an external interrupt source,
-	 * and then configure it as an input if it is not
-	*/
-
-	for (pin = S3C2410_GPF0; pin <= S3C2410_GPF7; pin++) {
-		s3c2410_pm_check_resume_pin(pin, pin - S3C2410_GPF0);
-	}
-
-	for (pin = S3C2410_GPG0; pin <= S3C2410_GPG7; pin++) {
-		s3c2410_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8);
-	}
-}
-
-void (*pm_cpu_prep)(void);
-void (*pm_cpu_sleep)(void);
-
-#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
-
-/* s3c2410_pm_enter
- *
- * central control for sleep/resume process
-*/
-
-static int s3c2410_pm_enter(suspend_state_t state)
-{
-	unsigned long regs_save[16];
-
-	/* ensure the debug is initialised (if enabled) */
-
-	s3c2410_pm_debug_init();
-
-	DBG("s3c2410_pm_enter(%d)\n", state);
-
-	if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
-		printk(KERN_ERR PFX "error: no cpu sleep functions set\n");
-		return -EINVAL;
-	}
-
-	if (state != PM_SUSPEND_MEM) {
-		printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
-		return -EINVAL;
-	}
-
-	/* check if we have anything to wake-up with... bad things seem
-	 * to happen if you suspend with no wakeup (system will often
-	 * require a full power-cycle)
-	*/
-
-	if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
-	    !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
-		printk(KERN_ERR PFX "No sources enabled for wake-up!\n");
-		printk(KERN_ERR PFX "Aborting sleep\n");
-		return -EINVAL;
-	}
-
-	/* prepare check area if configured */
-
-	s3c2410_pm_check_prepare();
-
-	/* store the physical address of the register recovery block */
-
-	s3c2410_sleep_save_phys = virt_to_phys(regs_save);
-
-	DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys);
-
-	/* save all necessary core registers not covered by the drivers */
-
-	s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));
-	s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
-	s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
-
-	/* set the irq configuration for wake */
-
-	s3c2410_pm_configure_extint();
-
-	DBG("sleep: irq wakeup masks: %08lx,%08lx\n",
-	    s3c_irqwake_intmask, s3c_irqwake_eintmask);
-
-	__raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
-	__raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
-
-	/* ack any outstanding external interrupts before we go to sleep */
-
-	__raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
-	__raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
-	__raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
-
-	/* call cpu specific preperation */
-
-	pm_cpu_prep();
-
-	/* flush cache back to ram */
-
-	flush_cache_all();
-
-	s3c2410_pm_check_store();
-
-	/* send the cpu to sleep... */
-
-	__raw_writel(0x00, S3C2410_CLKCON);  /* turn off clocks over sleep */
-
-	/* s3c2410_cpu_save will also act as our return point from when
-	 * we resume as it saves its own register state, so use the return
-	 * code to differentiate return from save and return from sleep */
-
-	if (s3c2410_cpu_save(regs_save) == 0) {
-		flush_cache_all();
-		pm_cpu_sleep();
-	}
-
-	/* restore the cpu state */
-
-	cpu_init();
-
-	/* restore the system state */
-
-	s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
-	s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
-	s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
-
-	s3c2410_pm_debug_init();
-
-	/* check what irq (if any) restored the system */
-
-	DBG("post sleep: IRQs 0x%08x, 0x%08x\n",
-	    __raw_readl(S3C2410_SRCPND),
-	    __raw_readl(S3C2410_EINTPEND));
-
-	s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
-				    s3c_irqwake_intmask);
-
-	s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
-				    s3c_irqwake_eintmask);
-
-	DBG("post sleep, preparing to return\n");
-
-	s3c2410_pm_check_restore();
-
-	/* ok, let's return from sleep */
+	if ( machine_is_aml_m5900() )
+		s3c2410_gpio_setpin(S3C2410_GPF2, 0);
 
-	DBG("S3C2410 PM Resume (post-restore)\n");
 	return 0;
 }
 
-/*
- * Called after processes are frozen, but before we shut down devices.
- */
-static int s3c2410_pm_prepare(suspend_state_t state)
+static int s3c2410_pm_add(struct sys_device *dev)
 {
+	pm_cpu_prep = s3c2410_pm_prepare;
+	pm_cpu_sleep = s3c2410_cpu_suspend;
+
 	return 0;
 }
 
-/*
- * Called after devices are re-setup, but before processes are thawed.
- */
-static int s3c2410_pm_finish(suspend_state_t state)
-{
-	return 0;
-}
-
-/*
- * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
- */
-static struct pm_ops s3c2410_pm_ops = {
-	.pm_disk_mode	= PM_DISK_FIRMWARE,
-	.prepare	= s3c2410_pm_prepare,
-	.enter		= s3c2410_pm_enter,
-	.finish		= s3c2410_pm_finish,
+#if defined(CONFIG_CPU_S3C2410)
+static struct sysdev_driver s3c2410_pm_driver = {
+	.add		= s3c2410_pm_add,
+	.resume		= s3c2410_pm_resume,
 };
 
-/* s3c2410_pm_init
- *
- * Attach the power management functions. This should be called
- * from the board specific initialisation if the board supports
- * it.
-*/
+/* register ourselves */
 
-int __init s3c2410_pm_init(void)
+static int __init s3c2410_pm_drvinit(void)
 {
-	printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n");
-
-	pm_set_ops(&s3c2410_pm_ops);
-	return 0;
+	return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver);
 }
+
+arch_initcall(s3c2410_pm_drvinit);
+#endif
+
+#if defined(CONFIG_CPU_S3C2440)
+static struct sysdev_driver s3c2440_pm_driver = {
+	.add		= s3c2410_pm_add,
+	.resume		= s3c2410_pm_resume,
+};
+
+static int __init s3c2440_pm_drvinit(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver);
+}
+
+arch_initcall(s3c2440_pm_drvinit);
+#endif
+
+#if defined(CONFIG_CPU_S3C2442)
+static struct sysdev_driver s3c2442_pm_driver = {
+	.add		= s3c2410_pm_add,
+	.resume		= s3c2410_pm_resume,
+};
+
+static int __init s3c2442_pm_drvinit(void)
+{
+	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver);
+}
+
+arch_initcall(s3c2442_pm_drvinit);
+#endif
diff --git a/arch/arm/mach-s3c2410/s3c2410-clock.c b/arch/arm/mach-s3c2410/s3c2410-clock.c
deleted file mode 100644
index 992cc6a..0000000
--- a/arch/arm/mach-s3c2410/s3c2410-clock.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2410-clock.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410,S3C2440,S3C2442 Clock control support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/sysdev.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/serial_core.h>
-
-#include <asm/mach/map.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-gpio.h>
-
-#include "s3c2410.h"
-#include "clock.h"
-#include "cpu.h"
-
-int s3c2410_clkcon_enable(struct clk *clk, int enable)
-{
-	unsigned int clocks = clk->ctrlbit;
-	unsigned long clkcon;
-
-	clkcon = __raw_readl(S3C2410_CLKCON);
-
-	if (enable)
-		clkcon |= clocks;
-	else
-		clkcon &= ~clocks;
-
-	/* ensure none of the special function bits set */
-	clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
-
-	__raw_writel(clkcon, S3C2410_CLKCON);
-
-	return 0;
-}
-
-static int s3c2410_upll_enable(struct clk *clk, int enable)
-{
-	unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
-	unsigned long orig = clkslow;
-
-	if (enable)
-		clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
-	else
-		clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
-
-	__raw_writel(clkslow, S3C2410_CLKSLOW);
-
-	/* if we started the UPLL, then allow to settle */
-
-	if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
-		udelay(200);
-
-	return 0;
-}
-
-/* standard clock definitions */
-
-static struct clk init_clocks_disable[] = {
-	{
-		.name		= "nand",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_NAND,
-	}, {
-		.name		= "sdi",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_SDI,
-	}, {
-		.name		= "adc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_ADC,
-	}, {
-		.name		= "i2c",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_IIC,
-	}, {
-		.name		= "iis",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_IIS,
-	}, {
-		.name		= "spi",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_SPI,
-	}
-};
-
-static struct clk init_clocks[] = {
-	{
-		.name		= "lcd",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_LCDC,
-	}, {
-		.name		= "gpio",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_GPIO,
-	}, {
-		.name		= "usb-host",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_USBH,
-	}, {
-		.name		= "usb-device",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_USBD,
-	}, {
-		.name		= "timers",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_PWMT,
-	}, {
-		.name		= "uart",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_UART0,
-	}, {
-		.name		= "uart",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_UART1,
-	}, {
-		.name		= "uart",
-		.id		= 2,
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_UART2,
-	}, {
-		.name		= "rtc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_RTC,
-	}, {
-		.name		= "watchdog",
-		.id		= -1,
-		.parent		= &clk_p,
-		.ctrlbit	= 0,
-	}, {
-		.name		= "usb-bus-host",
-		.id		= -1,
-		.parent		= &clk_usb_bus,
-	}, {
-		.name		= "usb-bus-gadget",
-		.id		= -1,
-		.parent		= &clk_usb_bus,
-	},
-};
-
-/* s3c2410_baseclk_add()
- *
- * Add all the clocks used by the s3c2410 or compatible CPUs
- * such as the S3C2440 and S3C2442.
- *
- * We cannot use a system device as we are needed before any
- * of the init-calls that initialise the devices are actually
- * done.
-*/
-
-int __init s3c2410_baseclk_add(void)
-{
-	unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
-	unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);
-	struct clk *clkp;
-	struct clk *xtal;
-	int ret;
-	int ptr;
-
-	clk_upll.enable = s3c2410_upll_enable;
-
-	if (s3c24xx_register_clock(&clk_usb_bus) < 0)
-		printk(KERN_ERR "failed to register usb bus clock\n");
-
-	/* register clocks from clock array */
-
-	clkp = init_clocks;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
-		/* ensure that we note the clock state */
-
-		clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
-
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-	}
-
-	/* We must be careful disabling the clocks we are not intending to
-	 * be using at boot time, as subsytems such as the LCD which do
-	 * their own DMA requests to the bus can cause the system to lockup
-	 * if they where in the middle of requesting bus access.
-	 *
-	 * Disabling the LCD clock if the LCD is active is very dangerous,
-	 * and therefore the bootloader should be careful to not enable
-	 * the LCD clock if it is not needed.
-	*/
-
-	/* install (and disable) the clocks we do not need immediately */
-
-	clkp = init_clocks_disable;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
-
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-
-		s3c2410_clkcon_enable(clkp, 0);
-	}
-
-	/* show the clock-slow value */
-
-	xtal = clk_get(NULL, "xtal");
-
-	printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
-	       print_mhz(clk_get_rate(xtal) /
-			 ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
-	       (clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
-	       (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
-	       (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
-
-	return 0;
-}
diff --git a/arch/arm/mach-s3c2410/s3c2410-dma.c b/arch/arm/mach-s3c2410/s3c2410-dma.c
deleted file mode 100644
index e67ba39..0000000
--- a/arch/arm/mach-s3c2410/s3c2410-dma.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2410-dma.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sysdev.h>
-#include <linux/serial_core.h>
-
-#include <asm/dma.h>
-#include <asm/arch/dma.h>
-#include "dma.h"
-
-#include "cpu.h"
-
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-ac97.h>
-#include <asm/arch/regs-mem.h>
-#include <asm/arch/regs-lcd.h>
-#include <asm/arch/regs-sdi.h>
-#include <asm/arch/regs-iis.h>
-#include <asm/arch/regs-spi.h>
-
-static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
-	[DMACH_XD0] = {
-		.name		= "xdreq0",
-		.channels[0]	= S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
-	},
-	[DMACH_XD1] = {
-		.name		= "xdreq1",
-		.channels[1]	= S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
-	},
-	[DMACH_SDI] = {
-		.name		= "sdi",
-		.channels[0]	= S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
-		.channels[2]	= S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
-		.channels[3]	= S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
-		.hw_addr.to	= S3C2410_PA_IIS + S3C2410_IISFIFO,
-		.hw_addr.from	= S3C2410_PA_IIS + S3C2410_IISFIFO,
-	},
-	[DMACH_SPI0] = {
-		.name		= "spi0",
-		.channels[1]	= S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
-		.hw_addr.to	= S3C2410_PA_SPI + S3C2410_SPTDAT,
-		.hw_addr.from	= S3C2410_PA_SPI + S3C2410_SPRDAT,
-	},
-	[DMACH_SPI1] = {
-		.name		= "spi1",
-		.channels[3]	= S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
-		.hw_addr.to	= S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
-		.hw_addr.from	= S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
-	},
-	[DMACH_UART0] = {
-		.name		= "uart0",
-		.channels[0]	= S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
-		.hw_addr.to	= S3C2410_PA_UART0 + S3C2410_UTXH,
-		.hw_addr.from	= S3C2410_PA_UART0 + S3C2410_URXH,
-	},
-	[DMACH_UART1] = {
-		.name		= "uart1",
-		.channels[1]	= S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
-		.hw_addr.to	= S3C2410_PA_UART1 + S3C2410_UTXH,
-		.hw_addr.from	= S3C2410_PA_UART1 + S3C2410_URXH,
-	},
-      	[DMACH_UART2] = {
-		.name		= "uart2",
-		.channels[3]	= S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
-		.hw_addr.to	= S3C2410_PA_UART2 + S3C2410_UTXH,
-		.hw_addr.from	= S3C2410_PA_UART2 + S3C2410_URXH,
-	},
-	[DMACH_TIMER] = {
-		.name		= "timer",
-		.channels[0]	= S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
-		.channels[2]	= S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
-		.channels[3]	= S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
-	},
-	[DMACH_I2S_IN] = {
-		.name		= "i2s-sdi",
-		.channels[1]	= S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
-		.channels[2]	= S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
-		.hw_addr.from	= S3C2410_PA_IIS + S3C2410_IISFIFO,
-	},
-	[DMACH_I2S_OUT] = {
-		.name		= "i2s-sdo",
-		.channels[2]	= S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
-		.hw_addr.to	= S3C2410_PA_IIS + S3C2410_IISFIFO,
-	},
-	[DMACH_USB_EP1] = {
-		.name		= "usb-ep1",
-		.channels[0]	= S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
-	},
-	[DMACH_USB_EP2] = {
-		.name		= "usb-ep2",
-		.channels[1]	= S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
-	},
-	[DMACH_USB_EP3] = {
-		.name		= "usb-ep3",
-		.channels[2]	= S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
-	},
-	[DMACH_USB_EP4] = {
-		.name		= "usb-ep4",
-		.channels[3]	=S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
-	},
-};
-
-static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
-			       struct s3c24xx_dma_map *map)
-{
-	chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
-	.select		= s3c2410_dma_select,
-	.dcon_mask	= 7 << 24,
-	.map		= s3c2410_dma_mappings,
-	.map_size	= ARRAY_SIZE(s3c2410_dma_mappings),
-};
-
-static int s3c2410_dma_add(struct sys_device *sysdev)
-{
-	return s3c24xx_dma_init_map(&s3c2410_dma_sel);
-}
-
-#if defined(CONFIG_CPU_S3C2410)
-static struct sysdev_driver s3c2410_dma_driver = {
-	.add	= s3c2410_dma_add,
-};
-
-static int __init s3c2410_dma_init(void)
-{
-	return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver);
-}
-
-arch_initcall(s3c2410_dma_init);
-#endif
-
-#if defined(CONFIG_CPU_S3C2442)
-/* S3C2442 DMA contains the same selection table as the S3C2410 */
-static struct sysdev_driver s3c2442_dma_driver = {
-	.add	= s3c2410_dma_add,
-};
-
-static int __init s3c2442_dma_init(void)
-{
-	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver);
-}
-
-arch_initcall(s3c2442_dma_init);
-#endif
-
diff --git a/arch/arm/mach-s3c2410/s3c2410-gpio.c b/arch/arm/mach-s3c2410/s3c2410-gpio.c
deleted file mode 100644
index ec3a276..0000000
--- a/arch/arm/mach-s3c2410/s3c2410-gpio.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2410-gpio.c
- *
- * Copyright (c) 2004-2006 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 GPIO support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-#include <asm/arch/regs-gpio.h>
-
-int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
-			   unsigned int config)
-{
-	void __iomem *reg = S3C24XX_EINFLT0;
-	unsigned long flags;
-	unsigned long val;
-
-	if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15)
-		return -1;
-
-	config &= 0xff;
-
-	pin -= S3C2410_GPG8;
-	reg += pin & ~3;
-
-	local_irq_save(flags);
-
-	/* update filter width and clock source */
-
-	val = __raw_readl(reg);
-	val &= ~(0xff << ((pin & 3) * 8));
-	val |= config << ((pin & 3) * 8);
-	__raw_writel(val, reg);
-
-	/* update filter enable */
-
-	val = __raw_readl(S3C24XX_EXTINT2);
-	val &= ~(1 << ((pin * 4) + 3));
-	val |= on << ((pin * 4) + 3);
-	__raw_writel(val, S3C24XX_EXTINT2);
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
diff --git a/arch/arm/mach-s3c2410/s3c2410-irq.c b/arch/arm/mach-s3c2410/s3c2410-irq.c
deleted file mode 100644
index c796c9c..0000000
--- a/arch/arm/mach-s3c2410/s3c2410-irq.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2410-irq.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/ptrace.h>
-#include <linux/sysdev.h>
-
-#include "cpu.h"
-#include "pm.h"
-
-static int s3c2410_irq_add(struct sys_device *sysdev)
-{
-	return 0;
-}
-
-static struct sysdev_driver s3c2410_irq_driver = {
-	.add		= s3c2410_irq_add,
-	.suspend	= s3c24xx_irq_suspend,
-	.resume		= s3c24xx_irq_resume,
-};
-
-static int s3c2410_irq_init(void)
-{
-	return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver);
-}
-
-arch_initcall(s3c2410_irq_init);
diff --git a/arch/arm/mach-s3c2410/s3c2410-pm.c b/arch/arm/mach-s3c2410/s3c2410-pm.c
deleted file mode 100644
index 8bb6e5e..0000000
--- a/arch/arm/mach-s3c2410/s3c2410-pm.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2410-pm.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-#include <linux/suspend.h>
-#include <linux/errno.h>
-#include <linux/time.h>
-#include <linux/sysdev.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-
-#include <asm/mach-types.h>
-
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/h1940.h>
-
-#include "cpu.h"
-#include "pm.h"
-
-#ifdef CONFIG_S3C2410_PM_DEBUG
-extern void pm_dbg(const char *fmt, ...);
-#define DBG(fmt...) pm_dbg(fmt)
-#else
-#define DBG(fmt...) printk(KERN_DEBUG fmt)
-#endif
-
-static void s3c2410_pm_prepare(void)
-{
-	/* ensure at least GSTATUS3 has the resume address */
-
-	__raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
-
-	DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
-	DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
-
-	if (machine_is_h1940()) {
-		void *base = phys_to_virt(H1940_SUSPEND_CHECK);
-		unsigned long ptr;
-		unsigned long calc = 0;
-
-		/* generate check for the bootloader to check on resume */
-
-		for (ptr = 0; ptr < 0x40000; ptr += 0x400)
-			calc += __raw_readl(base+ptr);
-
-		__raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
-	}
-
-	/* the RX3715 uses similar code and the same H1940 and the
-	 * same offsets for resume and checksum pointers */
-
-	if (machine_is_rx3715()) {
-		void *base = phys_to_virt(H1940_SUSPEND_CHECK);
-		unsigned long ptr;
-		unsigned long calc = 0;
-
-		/* generate check for the bootloader to check on resume */
-
-		for (ptr = 0; ptr < 0x40000; ptr += 0x4)
-			calc += __raw_readl(base+ptr);
-
-		__raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
-	}
-
-	if ( machine_is_aml_m5900() )
-		s3c2410_gpio_setpin(S3C2410_GPF2, 1);
-
-}
-
-static int s3c2410_pm_resume(struct sys_device *dev)
-{
-	unsigned long tmp;
-
-	/* unset the return-from-sleep flag, to ensure reset */
-
-	tmp = __raw_readl(S3C2410_GSTATUS2);
-	tmp &= S3C2410_GSTATUS2_OFFRESET;
-	__raw_writel(tmp, S3C2410_GSTATUS2);
-
-	if ( machine_is_aml_m5900() )
-		s3c2410_gpio_setpin(S3C2410_GPF2, 0);
-
-	return 0;
-}
-
-static int s3c2410_pm_add(struct sys_device *dev)
-{
-	pm_cpu_prep = s3c2410_pm_prepare;
-	pm_cpu_sleep = s3c2410_cpu_suspend;
-
-	return 0;
-}
-
-#if defined(CONFIG_CPU_S3C2410)
-static struct sysdev_driver s3c2410_pm_driver = {
-	.add		= s3c2410_pm_add,
-	.resume		= s3c2410_pm_resume,
-};
-
-/* register ourselves */
-
-static int __init s3c2410_pm_drvinit(void)
-{
-	return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver);
-}
-
-arch_initcall(s3c2410_pm_drvinit);
-#endif
-
-#if defined(CONFIG_CPU_S3C2440)
-static struct sysdev_driver s3c2440_pm_driver = {
-	.add		= s3c2410_pm_add,
-	.resume		= s3c2410_pm_resume,
-};
-
-static int __init s3c2440_pm_drvinit(void)
-{
-	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver);
-}
-
-arch_initcall(s3c2440_pm_drvinit);
-#endif
-
-#if defined(CONFIG_CPU_S3C2442)
-static struct sysdev_driver s3c2442_pm_driver = {
-	.add		= s3c2410_pm_add,
-	.resume		= s3c2410_pm_resume,
-};
-
-static int __init s3c2442_pm_drvinit(void)
-{
-	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver);
-}
-
-arch_initcall(s3c2442_pm_drvinit);
-#endif
diff --git a/arch/arm/mach-s3c2410/s3c2410-sleep.S b/arch/arm/mach-s3c2410/s3c2410-sleep.S
deleted file mode 100644
index 9179a10..0000000
--- a/arch/arm/mach-s3c2410/s3c2410-sleep.S
+++ /dev/null
@@ -1,68 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S
- *
- * Copyright (c) 2004 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 Power Manager (Suspend-To-RAM) support
- *
- * Based on PXA/SA1100 sleep code by:
- *	Nicolas Pitre, (c) 2002 Monta Vista Software Inc
- *	Cliff Brake, (c) 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/hardware.h>
-#include <asm/arch/map.h>
-
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-mem.h>
-#include <asm/arch/regs-serial.h>
-
-	/* s3c2410_cpu_suspend
-	 *
-	 * put the cpu into sleep mode
-	*/
-
-ENTRY(s3c2410_cpu_suspend)
-	@@ prepare cpu to sleep
-
-	ldr	r4, =S3C2410_REFRESH
-	ldr	r5, =S3C24XX_MISCCR
-	ldr	r6, =S3C2410_CLKCON
-	ldr	r7, [ r4 ]		@ get REFRESH (and ensure in TLB)
-	ldr	r8, [ r5 ]		@ get MISCCR (and ensure in TLB)
-	ldr	r9, [ r6 ]		@ get CLKCON (and ensure in TLB)
-
-	orr	r7, r7, #S3C2410_REFRESH_SELF	@ SDRAM sleep command
-	orr	r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
-	orr	r9, r9, #S3C2410_CLKCON_POWER	@ power down command
-
-	teq	pc, #0			@ first as a trial-run to load cache
-	bl	s3c2410_do_sleep
-	teq	r0, r0			@ now do it for real
-	b	s3c2410_do_sleep	@
-
-	@@ align next bit of code to cache line
-	.align	8
-s3c2410_do_sleep:
-	streq	r7, [ r4 ]			@ SDRAM sleep command
-	streq	r8, [ r5 ]			@ SDRAM power-down config
-	streq	r9, [ r6 ]			@ CPU sleep
-1:	beq	1b
-	mov	pc, r14
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index 4cdc0d7..1a86a98 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -31,10 +31,10 @@
 #include <asm/arch/regs-clock.h>
 #include <asm/arch/regs-serial.h>
 
-#include "s3c2410.h"
-#include "cpu.h"
-#include "devs.h"
-#include "clock.h"
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/clock.h>
 
 /* Initial IO mappings */
 
@@ -110,7 +110,7 @@
 
 /* need to register class before we actually register the device, and
  * we also need to ensure that it has been initialised before any of the
- * drivers even try to use it (even if not on an s3c2440 based system)
+ * drivers even try to use it (even if not on an s3c2410 based system)
  * as a driver which may support both 2410 and 2440 may try and use it.
 */
 
diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S
index 2018c2e..637aaba 100644
--- a/arch/arm/mach-s3c2410/sleep.S
+++ b/arch/arm/mach-s3c2410/sleep.S
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/sleep.S
+/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S
  *
  * Copyright (c) 2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -34,126 +34,35 @@
 #include <asm/arch/regs-mem.h>
 #include <asm/arch/regs-serial.h>
 
-/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
- * reset the UART configuration, only enable if you really need this!
-*/
-//#define CONFIG_DEBUG_RESUME
-
-	.text
-
-	/* s3c2410_cpu_save
+	/* s3c2410_cpu_suspend
 	 *
-	 * save enough of the CPU state to allow us to re-start
-	 * pm.c code. as we store items like the sp/lr, we will
-	 * end up returning from this function when the cpu resumes
-	 * so the return value is set to mark this.
-	 *
-	 * This arangement means we avoid having to flush the cache
-	 * from this code.
-	 *
-	 * entry:
-	 *	r0 = pointer to save block
-	 *
-	 * exit:
-	 *	r0 = 0 => we stored everything
-	 *	     1 => resumed from sleep
+	 * put the cpu into sleep mode
 	*/
 
-ENTRY(s3c2410_cpu_save)
-	stmfd	sp!, { r4 - r12, lr }
+ENTRY(s3c2410_cpu_suspend)
+	@@ prepare cpu to sleep
 
-	@@ store co-processor registers
+	ldr	r4, =S3C2410_REFRESH
+	ldr	r5, =S3C24XX_MISCCR
+	ldr	r6, =S3C2410_CLKCON
+	ldr	r7, [ r4 ]		@ get REFRESH (and ensure in TLB)
+	ldr	r8, [ r5 ]		@ get MISCCR (and ensure in TLB)
+	ldr	r9, [ r6 ]		@ get CLKCON (and ensure in TLB)
 
-	mrc	p15, 0, r4, c15, c1, 0	@ CP access register
-	mrc	p15, 0, r5, c13, c0, 0	@ PID
-	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
-	mrc	p15, 0, r7, c2, c0, 0	@ translation table base address
-	mrc	p15, 0, r8, c1, c0, 0	@ control register
+	orr	r7, r7, #S3C2410_REFRESH_SELF	@ SDRAM sleep command
+	orr	r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
+	orr	r9, r9, #S3C2410_CLKCON_POWER	@ power down command
 
-	stmia	r0, { r4 - r13 }
+	teq	pc, #0			@ first as a trial-run to load cache
+	bl	s3c2410_do_sleep
+	teq	r0, r0			@ now do it for real
+	b	s3c2410_do_sleep	@
 
-	mov	r0, #0
-	ldmfd	sp, { r4 - r12, pc }
-
-	@@ return to the caller, after having the MMU
-	@@ turned on, this restores the last bits from the
-	@@ stack
-resume_with_mmu:
-	mov	r0, #1
-	ldmfd	sp!, { r4 - r12, pc }
-
-	.ltorg
-
-	@@ the next bits sit in the .data segment, even though they
-	@@ happen to be code... the s3c2410_sleep_save_phys needs to be
-	@@ accessed by the resume code before it can restore the MMU.
-	@@ This means that the variable has to be close enough for the
-	@@ code to read it... since the .text segment needs to be RO,
-	@@ the data segment can be the only place to put this code.
-
-	.data
-
-	.global	s3c2410_sleep_save_phys
-s3c2410_sleep_save_phys:
-	.word	0
-
-	/* s3c2410_cpu_resume
-	 *
-	 * resume code entry for bootloader to call
-	 *
-	 * we must put this code here in the data segment as we have no
-	 * other way of restoring the stack pointer after sleep, and we
-	 * must not write to the code segment (code is read-only)
-	*/
-
-ENTRY(s3c2410_cpu_resume)
-	mov	r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
-	msr	cpsr_c, r0
-
-	@@ load UART to allow us to print the two characters for
-	@@ resume debug
-
-	mov	r2, #S3C24XX_PA_UART & 0xff000000
-	orr	r2, r2, #S3C24XX_PA_UART & 0xff000
-
-#if 0
-	/* SMDK2440 LED set */
-	mov	r14, #S3C24XX_PA_GPIO
-	ldr	r12, [ r14, #0x54 ]
-	bic	r12, r12, #3<<4
-	orr	r12, r12, #1<<7
-	str	r12, [ r14, #0x54 ]
-#endif
-
-#ifdef CONFIG_DEBUG_RESUME
-	mov	r3, #'L'
-	strb	r3, [ r2, #S3C2410_UTXH ]
-1001:
-	ldrb	r14, [ r3, #S3C2410_UTRSTAT ]
-	tst	r14, #S3C2410_UTRSTAT_TXE
-	beq	1001b
-#endif /* CONFIG_DEBUG_RESUME */
-
-	mov	r1, #0
-	mcr	p15, 0, r1, c8, c7, 0		@@ invalidate I & D TLBs
-	mcr	p15, 0, r1, c7, c7, 0		@@ invalidate I & D caches
-
-	ldr	r0, s3c2410_sleep_save_phys	@ address of restore block
-	ldmia	r0, { r4 - r13 }
-
-	mcr	p15, 0, r4, c15, c1, 0		@ CP access register
-	mcr	p15, 0, r5, c13, c0, 0		@ PID
-	mcr	p15, 0, r6, c3, c0, 0		@ Domain ID
-	mcr	p15, 0, r7, c2, c0, 0		@ translation table base
-
-#ifdef CONFIG_DEBUG_RESUME
-	mov	r3, #'R'
-	strb	r3, [ r2, #S3C2410_UTXH ]
-#endif
-
-	ldr	r2, =resume_with_mmu
-	mcr	p15, 0, r8, c1, c0, 0		@ turn on MMU, etc
-	nop					@ second-to-last before mmu
-	mov	pc, r2				@ go back to virtual address
-
-	.ltorg
+	@@ align next bit of code to cache line
+	.align	5
+s3c2410_do_sleep:
+	streq	r7, [ r4 ]			@ SDRAM sleep command
+	streq	r8, [ r5 ]			@ SDRAM power-down config
+	streq	r9, [ r6 ]			@ CPU sleep
+1:	beq	1b
+	mov	pc, r14
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
index 22b0e1c..bcd562a 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.c
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -35,7 +35,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "devs.h"
+#include <asm/plat-s3c24xx/devs.h>
 #include "usb-simtec.h"
 
 /* control power and monitor over-current events on various Simtec
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
new file mode 100644
index 0000000..befc5fd
--- /dev/null
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -0,0 +1,58 @@
+# arch/arm/mach-s3c2412/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config CPU_S3C2412
+	bool
+	depends on ARCH_S3C2410
+	select S3C2412_PM if PM
+	select S3C2412_DMA if S3C2410_DMA
+	help
+	  Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
+
+config CPU_S3C2412_ONLY
+	bool
+	depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
+		   !CPU_S3C2440 && !CPU_S3C2442 && !CPU_S3C2443 && CPU_S3C2412
+	default y if CPU_S3C2412
+
+config S3C2412_DMA
+	bool
+	depends on CPU_S3C2412
+	help
+	  Internal config node for S3C2412 DMA support
+
+config S3C2412_PM
+	bool
+	help
+	  Internal config node to apply S3C2412 power management
+
+
+menu "S3C2412 Machines"
+
+config MACH_SMDK2413
+	bool "SMDK2413"
+	select CPU_S3C2412
+	select MACH_S3C2413
+	select MACH_SMDK
+	help
+	  Say Y here if you are using an SMDK2413
+
+config MACH_S3C2413
+	bool
+	help
+	  Internal node for S3C2413 version of SMDK2413, so that
+	  machine_is_s3c2413() will work when MACH_SMDK2413 is
+	  selected
+
+config MACH_VSTMS
+	bool "VMSTMS"
+	select CPU_S3C2412
+	help
+	  Say Y here if you are using an VSTMS board
+
+
+endmenu
+
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile
new file mode 100644
index 0000000..f8e0116
--- /dev/null
+++ b/arch/arm/mach-s3c2412/Makefile
@@ -0,0 +1,21 @@
+# arch/arm/mach-s3c2412/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:=
+obj-				:=
+
+obj-$(CONFIG_CPU_S3C2412)	+= s3c2412.o
+obj-$(CONFIG_CPU_S3C2412)	+= irq.o
+obj-$(CONFIG_CPU_S3C2412)	+= clock.o
+obj-$(CONFIG_S3C2412_DMA)	+= dma.o
+obj-$(CONFIG_S3C2412_PM)	+= pm.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_SMDK2413)	+= mach-smdk2413.o
+obj-$(CONFIG_MACH_VSTMS)	+= mach-vstms.o
diff --git a/arch/arm/mach-s3c2410/s3c2412-clock.c b/arch/arm/mach-s3c2412/clock.c
similarity index 98%
rename from arch/arm/mach-s3c2410/s3c2412-clock.c
rename to arch/arm/mach-s3c2412/clock.c
index 8f94ad8..6a8e444 100644
--- a/arch/arm/mach-s3c2410/s3c2412-clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2412-clock.c
+/* linux/arch/arm/mach-s3c2412/clock.c
  *
  * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -41,9 +41,9 @@
 #include <asm/arch/regs-clock.h>
 #include <asm/arch/regs-gpio.h>
 
-#include "s3c2412.h"
-#include "clock.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/s3c2412.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 /* We currently have to assume that the system is running
  * from the XTPll input, and that all ***REFCLKs are being
diff --git a/arch/arm/mach-s3c2410/s3c2412-dma.c b/arch/arm/mach-s3c2412/dma.c
similarity index 96%
rename from arch/arm/mach-s3c2410/s3c2412-dma.c
rename to arch/arm/mach-s3c2412/dma.c
index 138f726..d0f4695 100644
--- a/arch/arm/mach-s3c2410/s3c2412-dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2412-dma.c
+/* linux/arch/arm/mach-s3c2412/dma.c
  *
  * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -21,8 +21,8 @@
 #include <asm/arch/dma.h>
 #include <asm/io.h>
 
-#include "dma.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/dma.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 #include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
@@ -146,6 +146,7 @@
 
 static int s3c2412_dma_add(struct sys_device *sysdev)
 {
+	s3c2410_dma_init();
 	return s3c24xx_dma_init_map(&s3c2412_dma_sel);
 }
 
diff --git a/arch/arm/mach-s3c2410/s3c2412-irq.c b/arch/arm/mach-s3c2412/irq.c
similarity index 95%
rename from arch/arm/mach-s3c2410/s3c2412-irq.c
rename to arch/arm/mach-s3c2412/irq.c
index ffcc30b..e89dbdc 100644
--- a/arch/arm/mach-s3c2410/s3c2412-irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2412/s3c2412-irq.c
+/* linux/arch/arm/mach-s3c2412/irq.c
  *
  * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -35,9 +35,9 @@
 #include <asm/arch/regs-irq.h>
 #include <asm/arch/regs-gpio.h>
 
-#include "cpu.h"
-#include "irq.h"
-#include "pm.h"
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/irq.h>
+#include <asm/plat-s3c24xx/pm.h>
 
 /* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
  * having them turn up in both the INT* and the EINT* registers. Whilst
diff --git a/arch/arm/mach-s3c2410/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
similarity index 67%
rename from arch/arm/mach-s3c2410/mach-smdk2413.c
rename to arch/arm/mach-s3c2412/mach-smdk2413.c
index 4f89abd..b5befce 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2413.c
+++ b/arch/arm/mach-s3c2412/mach-smdk2413.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/mach-smdk2413.c
+/* linux/arch/arm/mach-s3c2412/mach-smdk2413.c
  *
  * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -37,15 +37,16 @@
 #include <asm/arch/regs-lcd.h>
 
 #include <asm/arch/idle.h>
+#include <asm/arch/udc.h>
 #include <asm/arch/fb.h>
 
-#include "s3c2410.h"
-#include "s3c2412.h"
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/s3c2412.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
-#include "common-smdk.h"
+#include <asm/plat-s3c24xx/common-smdk.h>
 
 static struct map_desc smdk2413_iodesc[] __initdata = {
 };
@@ -75,12 +76,38 @@
 	}
 };
 
+static void smdk2413_udc_pullup(enum s3c2410_udc_cmd_e cmd)
+{
+	printk(KERN_DEBUG "udc: pullup(%d)\n",cmd);
+
+	switch (cmd)
+	{
+		case S3C2410_UDC_P_ENABLE :
+			s3c2410_gpio_setpin(S3C2410_GPF2, 1);
+			break;
+		case S3C2410_UDC_P_DISABLE :
+			s3c2410_gpio_setpin(S3C2410_GPF2, 0);
+			break;
+		case S3C2410_UDC_P_RESET :
+			break;
+		default:
+			break;
+	}
+}
+
+
+static struct s3c2410_udc_mach_info smdk2413_udc_cfg __initdata = {
+	.udc_command		= smdk2413_udc_pullup,
+};
+
+
 static struct platform_device *smdk2413_devices[] __initdata = {
 	&s3c_device_usb,
 	//&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c,
 	&s3c_device_iis,
+	&s3c_device_usbgadget,
 };
 
 static struct s3c24xx_board smdk2413_board __initdata = {
@@ -109,7 +136,19 @@
 }
 
 static void __init smdk2413_machine_init(void)
-{
+{	/* Turn off suspend on both USB ports, and switch the
+	 * selectable USB port to USB device mode. */
+
+	s3c2410_gpio_setpin(S3C2410_GPF2, 0);
+	s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPIO_OUTPUT);
+
+	s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+			      S3C2410_MISCCR_USBSUSPND0 |
+			      S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+
+ 	s3c24xx_udc_set_platdata(&smdk2413_udc_cfg);
+
 	smdk_machine_init();
 }
 
@@ -126,6 +165,19 @@
 	.timer		= &s3c24xx_timer,
 MACHINE_END
 
+MACHINE_START(SMDK2412, "SMDK2412")
+	/* Maintainer: Ben Dooks <ben@fluff.org> */
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+
+	.fixup		= smdk2413_fixup,
+	.init_irq	= s3c24xx_init_irq,
+	.map_io		= smdk2413_map_io,
+	.init_machine	= smdk2413_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
+
 MACHINE_START(SMDK2413, "SMDK2413")
 	/* Maintainer: Ben Dooks <ben@fluff.org> */
 	.phys_io	= S3C2410_PA_UART,
diff --git a/arch/arm/mach-s3c2410/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c
similarity index 93%
rename from arch/arm/mach-s3c2410/mach-vstms.c
rename to arch/arm/mach-s3c2412/mach-vstms.c
index 0360e10..4231b54 100644
--- a/arch/arm/mach-s3c2410/mach-vstms.c
+++ b/arch/arm/mach-s3c2412/mach-vstms.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/mach-vstms.c
+/* linux/arch/arm/mach-s3c2412/mach-vstms.c
  *
  * (C) 2006 Thomas Gleixner <tglx@linutronix.de>
  *
@@ -28,7 +28,6 @@
 #include <asm/mach/irq.h>
 
 #include <asm/hardware.h>
-#include <asm/hardware/iomd.h>
 #include <asm/setup.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -43,11 +42,11 @@
 
 #include <asm/arch/nand.h>
 
-#include "s3c2410.h"
-#include "s3c2412.h"
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/s3c2412.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 
 static struct map_desc vstms_iodesc[] __initdata = {
diff --git a/arch/arm/mach-s3c2410/s3c2412-pm.c b/arch/arm/mach-s3c2412/pm.c
similarity index 94%
rename from arch/arm/mach-s3c2410/s3c2412-pm.c
rename to arch/arm/mach-s3c2412/pm.c
index 19b6332..8988dac 100644
--- a/arch/arm/mach-s3c2410/s3c2412-pm.c
+++ b/arch/arm/mach-s3c2412/pm.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2412-pm.c
+/* linux/arch/arm/mach-s3c2412/pm.c
  *
  * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -28,10 +28,10 @@
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-dsc.h>
 
-#include "cpu.h"
-#include "pm.h"
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
 
-#include "s3c2412.h"
+#include <asm/plat-s3c24xx/s3c2412.h>
 
 static void s3c2412_cpu_suspend(void)
 {
diff --git a/arch/arm/mach-s3c2410/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
similarity index 94%
rename from arch/arm/mach-s3c2410/s3c2412.c
rename to arch/arm/mach-s3c2412/s3c2412.c
index 2f651a8..aafe0bc 100644
--- a/arch/arm/mach-s3c2410/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2412.c
+/* linux/arch/arm/mach-s3c2412/s3c2412.c
  *
  * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -38,11 +38,11 @@
 #include <asm/arch/regs-gpioj.h>
 #include <asm/arch/regs-dsc.h>
 
-#include "s3c2412.h"
-#include "cpu.h"
-#include "devs.h"
-#include "clock.h"
-#include "pm.h"
+#include <asm/plat-s3c24xx/s3c2412.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/pm.h>
 
 #ifndef CONFIG_CPU_S3C2412_ONLY
 void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
new file mode 100644
index 0000000..e3bfda0
--- /dev/null
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -0,0 +1,71 @@
+# arch/arm/mach-s3c2440/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config CPU_S3C2440
+	bool
+	depends on ARCH_S3C2410
+	select S3C2410_CLOCK
+	select S3C2410_PM if PM
+	select S3C2410_GPIO
+	select S3C2440_DMA if S3C2410_DMA
+	select CPU_S3C244X
+	help
+	  Support for S3C2440 Samsung Mobile CPU based systems.
+
+config S3C2440_DMA
+	bool
+	depends on ARCH_S3C2410 && CPU_S3C24405B
+	help
+	  Support for S3C2440 specific DMA code5A
+
+
+menu "S3C2440 Machines"
+
+config MACH_ANUBIS
+	bool "Simtec Electronics ANUBIS"
+	select CPU_S3C2440
+	select PM_SIMTEC if PM
+	help
+	  Say Y here if you are using the Simtec Electronics ANUBIS
+	  development system
+
+config MACH_OSIRIS
+	bool "Simtec IM2440D20 (OSIRIS) module"
+	select CPU_S3C2440
+	select PM_SIMTEC if PM
+	help
+	  Say Y here if you are using the Simtec IM2440D20 module, also
+	  known as the Osiris.
+
+config MACH_RX3715
+	bool "HP iPAQ rx3715"
+	select CPU_S3C2440
+	select PM_H1940 if PM
+	help
+	  Say Y here if you are using the HP iPAQ rx3715.
+
+config ARCH_S3C2440
+	bool "SMDK2440"
+	select CPU_S3C2440
+	select MACH_SMDK
+	help
+	  Say Y here if you are using the SMDK2440.
+
+config MACH_NEXCODER_2440
+ 	bool "NexVision NEXCODER 2440 Light Board"
+ 	select CPU_S3C2440
+	help
+ 	  Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
+
+config SMDK2440_CPU2440
+	bool "SMDK2440 with S3C2440 CPU module"
+	depends on ARCH_S3C2440
+	default y if ARCH_S3C2440
+	select CPU_S3C2440
+
+
+endmenu
+
diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile
new file mode 100644
index 0000000..c81ed62
--- /dev/null
+++ b/arch/arm/mach-s3c2440/Makefile
@@ -0,0 +1,23 @@
+# arch/arm/mach-s3c2440/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:=
+obj-				:=
+
+obj-$(CONFIG_CPU_S3C2440)	+= s3c2440.o dsc.o
+obj-$(CONFIG_CPU_S3C2440)	+= irq.o
+obj-$(CONFIG_CPU_S3C2440)	+= clock.o
+obj-$(CONFIG_S3C2440_DMA)	+= dma.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_ANUBIS)	+= mach-anubis.o
+obj-$(CONFIG_MACH_OSIRIS)	+= mach-osiris.o
+obj-$(CONFIG_MACH_RX3715)	+= mach-rx3715.o
+obj-$(CONFIG_ARCH_S3C2440)	+= mach-smdk2440.o
+obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
diff --git a/arch/arm/mach-s3c2410/s3c2440-clock.c b/arch/arm/mach-s3c2440/clock.c
similarity index 96%
rename from arch/arm/mach-s3c2410/s3c2440-clock.c
rename to arch/arm/mach-s3c2440/clock.c
index ba13c1d..79e2ea4 100644
--- a/arch/arm/mach-s3c2410/s3c2440-clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2440-clock.c
+/* linux/arch/arm/mach-s3c2440/clock.c
  *
  * Copyright (c) 2004-2005 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
@@ -41,8 +41,8 @@
 
 #include <asm/arch/regs-clock.h>
 
-#include "clock.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 /* S3C2440 extended clock support */
 
diff --git a/arch/arm/mach-s3c2410/s3c2440-dma.c b/arch/arm/mach-s3c2440/dma.c
similarity index 83%
rename from arch/arm/mach-s3c2410/s3c2440-dma.c
rename to arch/arm/mach-s3c2440/dma.c
index 47b861b..cd035a3 100644
--- a/arch/arm/mach-s3c2410/s3c2440-dma.c
+++ b/arch/arm/mach-s3c2440/dma.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2440-dma.c
+/* linux/arch/arm/mach-s3c2440/dma.c
  *
  * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -19,9 +19,9 @@
 
 #include <asm/dma.h>
 #include <asm/arch/dma.h>
-#include "dma.h"
 
-#include "cpu.h"
+#include <asm/plat-s3c24xx/dma.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 #include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
@@ -147,8 +147,53 @@
 	.map_size	= ARRAY_SIZE(s3c2440_dma_mappings),
 };
 
+static struct s3c24xx_dma_order __initdata s3c2440_dma_order = {
+	.channels	= {
+		[DMACH_SDI]	= {
+			.list	= {
+				[0]	= 3 | DMA_CH_VALID,
+				[1]	= 2 | DMA_CH_VALID,
+				[2]	= 1 | DMA_CH_VALID,
+				[3]	= 0 | DMA_CH_VALID,
+			},
+		},
+		[DMACH_I2S_IN]	= {
+			.list	= {
+				[0]	= 1 | DMA_CH_VALID,
+				[1]	= 2 | DMA_CH_VALID,
+			},
+		},
+		[DMACH_I2S_OUT]	= {
+			.list	= {
+				[0]	= 2 | DMA_CH_VALID,
+				[1]	= 1 | DMA_CH_VALID,
+			},
+		},
+		[DMACH_PCM_IN] = {
+			.list	= {
+				[0]	= 2 | DMA_CH_VALID,
+				[1]	= 1 | DMA_CH_VALID,
+			},
+		},
+		[DMACH_PCM_OUT] = {
+			.list	= {
+				[0]	= 1 | DMA_CH_VALID,
+				[1]	= 3 | DMA_CH_VALID,
+			},
+		},
+		[DMACH_MIC_IN] = {
+			.list	= {
+				[0]	= 3 | DMA_CH_VALID,
+				[1]	= 2 | DMA_CH_VALID,
+			},
+		},
+	},
+};
+
 static int s3c2440_dma_add(struct sys_device *sysdev)
 {
+	s3c2410_dma_init();
+	s3c24xx_dma_order_set(&s3c2440_dma_order);
 	return s3c24xx_dma_init_map(&s3c2440_dma_sel);
 }
 
diff --git a/arch/arm/mach-s3c2410/s3c2440-dsc.c b/arch/arm/mach-s3c2440/dsc.c
similarity index 90%
rename from arch/arm/mach-s3c2410/s3c2440-dsc.c
rename to arch/arm/mach-s3c2440/dsc.c
index c92ea66..2995ff5 100644
--- a/arch/arm/mach-s3c2410/s3c2440-dsc.c
+++ b/arch/arm/mach-s3c2440/dsc.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2440-dsc.c
+/* linux/arch/arm/mach-s3c2440/dsc.c
  *
  * Copyright (c) 2004-2005 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
@@ -27,8 +27,8 @@
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-dsc.h>
 
-#include "cpu.h"
-#include "s3c2440.h"
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/s3c2440.h>
 
 int s3c2440_set_dsc(unsigned int pin, unsigned int value)
 {
diff --git a/arch/arm/mach-s3c2410/s3c2440-irq.c b/arch/arm/mach-s3c2440/irq.c
similarity index 95%
rename from arch/arm/mach-s3c2410/s3c2440-irq.c
rename to arch/arm/mach-s3c2440/irq.c
index 1ba19b2..1069d13 100644
--- a/arch/arm/mach-s3c2410/s3c2440-irq.c
+++ b/arch/arm/mach-s3c2440/irq.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2440-irq.c
+/* linux/arch/arm/mach-s3c2440/irq.c
  *
  * Copyright (c) 2003,2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -35,9 +35,9 @@
 #include <asm/arch/regs-irq.h>
 #include <asm/arch/regs-gpio.h>
 
-#include "cpu.h"
-#include "pm.h"
-#include "irq.h"
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+#include <asm/plat-s3c24xx/irq.h>
 
 /* WDT/AC97 */
 
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
similarity index 97%
rename from arch/arm/mach-s3c2410/mach-anubis.c
rename to arch/arm/mach-s3c2440/mach-anubis.c
index 0fad0c2..3f0288e 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2440/mach-anubis.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/mach-anubis.c
+/* linux/arch/arm/mach-s3c2440/mach-anubis.c
  *
  * Copyright (c) 2003-2005 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
@@ -42,9 +42,9 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 #define COPYRIGHT ", (c) 2005 Simtec Electronics"
 
diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c
similarity index 94%
rename from arch/arm/mach-s3c2410/mach-nexcoder.c
rename to arch/arm/mach-s3c2440/mach-nexcoder.c
index d6dfdad..6d551d8 100644
--- a/arch/arm/mach-s3c2410/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2440/mach-nexcoder.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/mach-nexcoder.c
+/* linux/arch/arm/mach-s3c2440/mach-nexcoder.c
  *
  * Copyright (c) 2004 Nex Vision
  *   Guillaume GOURAT <guillaume.gourat@nexvision.tv>
@@ -38,11 +38,11 @@
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-serial.h>
 
-#include "s3c2410.h"
-#include "s3c2440.h"
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/s3c2440.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 static struct map_desc nexcoder_iodesc[] __initdata = {
 	/* nothing here yet */
diff --git a/arch/arm/mach-s3c2410/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
similarity index 97%
rename from arch/arm/mach-s3c2410/mach-osiris.c
rename to arch/arm/mach-s3c2440/mach-osiris.c
index 37b4085..2ed8e51 100644
--- a/arch/arm/mach-s3c2410/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/mach-osiris.c
+/* linux/arch/arm/mach-s3c2440/mach-osiris.c
  *
  * Copyright (c) 2005 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
@@ -41,9 +41,9 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 /* onboard perihpheral map */
 
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
similarity index 96%
rename from arch/arm/mach-s3c2410/mach-rx3715.c
rename to arch/arm/mach-s3c2440/mach-rx3715.c
index ecbcdf7..480ccde 100644
--- a/arch/arm/mach-s3c2410/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/mach-rx3715.c
+/* linux/arch/arm/mach-s3c2440/mach-rx3715.c
  *
  * Copyright (c) 2003,2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -33,7 +33,6 @@
 #include <asm/mach/irq.h>
 
 #include <asm/hardware.h>
-#include <asm/hardware/iomd.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
@@ -46,10 +45,10 @@
 #include <asm/arch/nand.h>
 #include <asm/arch/fb.h>
 
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
-#include "pm.h"
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
 
 static struct map_desc rx3715_iodesc[] __initdata = {
 	/* dump ISA space somewhere unused */
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c
similarity index 93%
rename from arch/arm/mach-s3c2410/mach-smdk2440.c
rename to arch/arm/mach-s3c2440/mach-smdk2440.c
index 2b61f4e..c17eb5b 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2440/mach-smdk2440.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/mach-smdk2440.c
+/* linux/arch/arm/mach-s3c2440/mach-smdk2440.c
  *
  * Copyright (c) 2004,2005 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -27,12 +27,10 @@
 #include <asm/mach/irq.h>
 
 #include <asm/hardware.h>
-#include <asm/hardware/iomd.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-//#include <asm/debug-ll.h>
 #include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-lcd.h>
@@ -40,13 +38,13 @@
 #include <asm/arch/idle.h>
 #include <asm/arch/fb.h>
 
-#include "s3c2410.h"
-#include "s3c2440.h"
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/s3c2440.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
-#include "common-smdk.h"
+#include <asm/plat-s3c24xx/common-smdk.h>
 
 static struct map_desc smdk2440_iodesc[] __initdata = {
 	/* ISA IO Space map (memory space selected by A24) */
@@ -144,6 +142,7 @@
 #endif
 
 	.lpcsel		= ((0xCE6) & ~7) | 1<<4,
+	.type		= S3C2410_LCDCON1_TFT16BPP,
 
 	.width		= 240,
 	.height		= 320,
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
similarity index 88%
rename from arch/arm/mach-s3c2410/s3c2440.c
rename to arch/arm/mach-s3c2440/s3c2440.c
index 344eb27..90e1da6 100644
--- a/arch/arm/mach-s3c2410/s3c2440.c
+++ b/arch/arm/mach-s3c2440/s3c2440.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2440.c
+/* linux/arch/arm/mach-s3c2440/s3c2440.c
  *
  * Copyright (c) 2004-2006 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
@@ -29,9 +29,9 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "s3c2440.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/s3c2440.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 static struct sys_device s3c2440_sysdev = {
 	.cls		= &s3c2440_sysclass,
diff --git a/arch/arm/mach-s3c2442/Kconfig b/arch/arm/mach-s3c2442/Kconfig
new file mode 100644
index 0000000..bf8d87a
--- /dev/null
+++ b/arch/arm/mach-s3c2442/Kconfig
@@ -0,0 +1,27 @@
+# arch/arm/mach-s3c2442/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config CPU_S3C2442
+	bool
+	depends on ARCH_S3C2420
+	select S3C2410_CLOCK
+	select S3C2410_GPIO
+	select S3C2410_PM if PM
+	select CPU_S3C244X
+	help
+	  Support for S3C2442 Samsung Mobile CPU based systems.
+
+
+menu "S3C2442 Machines"
+
+config SMDK2440_CPU2442
+	bool "SMDM2440 with S3C2442 CPU module"
+	depends on ARCH_S3C2440
+	select CPU_S3C2442
+
+
+endmenu
+
diff --git a/arch/arm/mach-s3c2442/Makefile b/arch/arm/mach-s3c2442/Makefile
new file mode 100644
index 0000000..2a909c6
--- /dev/null
+++ b/arch/arm/mach-s3c2442/Makefile
@@ -0,0 +1,16 @@
+# arch/arm/mach-s3c2442/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:=
+obj-				:=
+
+obj-$(CONFIG_CPU_S3C2442)	+= s3c2442.o
+obj-$(CONFIG_CPU_S3C2442)	+= clock.o
+
+# Machine support
+
diff --git a/arch/arm/mach-s3c2410/s3c2442-clock.c b/arch/arm/mach-s3c2442/clock.c
similarity index 96%
rename from arch/arm/mach-s3c2410/s3c2442-clock.c
rename to arch/arm/mach-s3c2442/clock.c
index 4e292ca..5b9e830 100644
--- a/arch/arm/mach-s3c2410/s3c2442-clock.c
+++ b/arch/arm/mach-s3c2442/clock.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2442-clock.c
+/* linux/arch/arm/mach-s3c2442/clock.c
  *
  * Copyright (c) 2004-2005 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
@@ -41,8 +41,8 @@
 
 #include <asm/arch/regs-clock.h>
 
-#include "clock.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 /* S3C2442 extended clock support */
 
diff --git a/arch/arm/mach-s3c2410/s3c2442.c b/arch/arm/mach-s3c2442/s3c2442.c
similarity index 86%
rename from arch/arm/mach-s3c2410/s3c2442.c
rename to arch/arm/mach-s3c2442/s3c2442.c
index 428732e..fbf8264 100644
--- a/arch/arm/mach-s3c2410/s3c2442.c
+++ b/arch/arm/mach-s3c2442/s3c2442.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2442.c
+/* linux/arch/arm/mach-s3c2442/s3c2442.c
  *
  * Copyright (c) 2006 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
@@ -19,8 +19,8 @@
 #include <linux/serial_core.h>
 #include <linux/sysdev.h>
 
-#include "s3c2442.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/s3c2442.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 static struct sys_device s3c2442_sysdev = {
 	.cls		= &s3c2442_sysclass,
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
new file mode 100644
index 0000000..c649bb2
--- /dev/null
+++ b/arch/arm/mach-s3c2443/Kconfig
@@ -0,0 +1,29 @@
+# arch/arm/mach-s3c2443/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config CPU_S3C2443
+	bool
+	depends on ARCH_S3C2410
+	select S3C2443_DMA if S3C2410_DMA
+	help
+	  Support for the S3C2443 SoC from the S3C24XX line
+
+config S3C2443_DMA
+	bool
+	depends on CPU_S3C2443
+	help
+	  Internal config node for S3C2443 DMA support
+
+menu "S3C2443 Machines"
+
+config MACH_SMDK2443
+	bool "SMDK2443"
+	select CPU_S3C2443
+	select MACH_SMDK
+	help
+	  Say Y here if you are using an SMDK2443
+
+endmenu
diff --git a/arch/arm/mach-s3c2443/Makefile b/arch/arm/mach-s3c2443/Makefile
new file mode 100644
index 0000000..d1843c9
--- /dev/null
+++ b/arch/arm/mach-s3c2443/Makefile
@@ -0,0 +1,20 @@
+# arch/arm/mach-s3c2443/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:=
+obj-				:=
+
+obj-$(CONFIG_CPU_S3C2443)	+= s3c2443.o
+obj-$(CONFIG_CPU_S3C2443)	+= irq.o
+obj-$(CONFIG_CPU_S3C2443)	+= clock.o
+
+obj-$(CONFIG_S3C2443_DMA)	+= dma.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_SMDK2443)	+= mach-smdk2443.o
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
new file mode 100644
index 0000000..dd2272f
--- /dev/null
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -0,0 +1,1007 @@
+/* linux/arch/arm/mach-s3c2443/clock.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2443 Clock control support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/map.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-s3c2443-clock.h>
+
+#include <asm/plat-s3c24xx/s3c2443.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+/* We currently have to assume that the system is running
+ * from the XTPll input, and that all ***REFCLKs are being
+ * fed from it, as we cannot read the state of OM[4] from
+ * software.
+ *
+ * It would be possible for each board initialisation to
+ * set the correct muxing at initialisation
+*/
+
+static int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
+{
+	unsigned int clocks = clk->ctrlbit;
+	unsigned long clkcon;
+
+	clkcon = __raw_readl(S3C2443_HCLKCON);
+
+	if (enable)
+		clkcon |= clocks;
+	else
+		clkcon &= ~clocks;
+
+	__raw_writel(clkcon, S3C2443_HCLKCON);
+
+	return 0;
+}
+
+static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
+{
+	unsigned int clocks = clk->ctrlbit;
+	unsigned long clkcon;
+
+	clkcon = __raw_readl(S3C2443_PCLKCON);
+
+	if (enable)
+		clkcon |= clocks;
+	else
+		clkcon &= ~clocks;
+
+	__raw_writel(clkcon, S3C2443_HCLKCON);
+
+	return 0;
+}
+
+static int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
+{
+	unsigned int clocks = clk->ctrlbit;
+	unsigned long clkcon;
+
+	clkcon = __raw_readl(S3C2443_SCLKCON);
+
+	if (enable)
+		clkcon |= clocks;
+	else
+		clkcon &= ~clocks;
+
+	__raw_writel(clkcon, S3C2443_SCLKCON);
+
+	return 0;
+}
+
+static unsigned long s3c2443_roundrate_clksrc(struct clk *clk,
+					      unsigned long rate,
+					      unsigned int max)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	int div;
+
+	if (rate > parent_rate)
+		return parent_rate;
+
+	/* note, we remove the +/- 1 calculations as they cancel out */
+
+	div = (rate / parent_rate);
+
+	if (div < 1)
+		div = 1;
+	else if (div > max)
+		div = max;
+
+	return parent_rate / div;
+}
+
+static unsigned long s3c2443_roundrate_clksrc4(struct clk *clk,
+					       unsigned long rate)
+{
+	return s3c2443_roundrate_clksrc(clk, rate, 4);
+}
+
+static unsigned long s3c2443_roundrate_clksrc16(struct clk *clk,
+						unsigned long rate)
+{
+	return s3c2443_roundrate_clksrc(clk, rate, 16);
+}
+
+static unsigned long s3c2443_roundrate_clksrc256(struct clk *clk,
+						 unsigned long rate)
+{
+	return s3c2443_roundrate_clksrc(clk, rate, 256);
+}
+
+/* clock selections */
+
+/* CPU EXTCLK input */
+static struct clk clk_ext = {
+	.name		= "ext",
+	.id		= -1,
+};
+
+static struct clk clk_mpllref = {
+	.name		= "mpllref",
+	.parent		= &clk_xtal,
+	.id		= -1,
+};
+
+#if 0
+static struct clk clk_mpll = {
+	.name		= "mpll",
+	.parent		= &clk_mpllref,
+	.id		= -1,
+};
+#endif
+
+static struct clk clk_epllref;
+
+static struct clk clk_epll = {
+	.name		= "epll",
+	.parent		= &clk_epllref,
+	.id		= -1,
+};
+
+static struct clk clk_i2s_ext = {
+	.name		= "i2s-ext",
+	.id		= -1,
+};
+
+static int s3c2443_setparent_epllref(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+
+	clksrc &= ~S3C2443_CLKSRC_EPLLREF_MASK;
+
+	if (parent == &clk_xtal)
+		clksrc |= S3C2443_CLKSRC_EPLLREF_XTAL;
+	else if (parent == &clk_ext)
+		clksrc |= S3C2443_CLKSRC_EPLLREF_EXTCLK;
+	else if (parent != &clk_mpllref)
+		return -EINVAL;
+
+	__raw_writel(clksrc, S3C2443_CLKSRC);
+	clk->parent = parent;
+
+	return 0;
+}
+
+static struct clk clk_epllref = {
+	.name		= "epllref",
+	.id		= -1,
+	.set_parent	= s3c2443_setparent_epllref,
+};
+
+static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV0);
+
+	div  &= S3C2443_CLKDIV0_EXTDIV_MASK;
+	div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1);	/* x2 */
+
+	return parent_rate / (div + 1);
+}
+
+static struct clk clk_mdivclk = {
+	.name		= "mdivclk",
+	.parent		= &clk_mpllref,
+	.id		= -1,
+	.get_rate	= s3c2443_getrate_mdivclk,
+};
+
+
+static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+
+	clksrc &= ~(S3C2443_CLKSRC_MSYSCLK_MPLL |
+		    S3C2443_CLKSRC_EXTCLK_DIV);
+
+	if (parent == &clk_mpll)
+		clksrc |= S3C2443_CLKSRC_MSYSCLK_MPLL;
+	else if (parent == &clk_mdivclk)
+		clksrc |= S3C2443_CLKSRC_EXTCLK_DIV;
+	else if (parent != &clk_mpllref)
+		return -EINVAL;
+
+	__raw_writel(clksrc, S3C2443_CLKSRC);
+	clk->parent = parent;
+
+	return 0;
+}
+
+static struct clk clk_msysclk = {
+	.name		= "msysclk",
+	.parent		= &clk_xtal,
+	.id		= -1,
+	.set_parent	= s3c2443_setparent_msysclk,
+};
+
+
+/* esysclk
+ *
+ * this is sourced from either the EPLL or the EPLLref clock
+*/
+
+static int s3c2443_setparent_esysclk(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+
+	if (parent == &clk_epll)
+		clksrc |= S3C2443_CLKSRC_ESYSCLK_EPLL;
+	else if (parent == &clk_epllref)
+		clksrc &= ~S3C2443_CLKSRC_ESYSCLK_EPLL;
+	else
+		return -EINVAL;
+
+	__raw_writel(clksrc, S3C2443_CLKSRC);
+	clk->parent = parent;
+
+	return 0;
+}
+
+static struct clk clk_esysclk = {
+	.name		= "esysclk",
+	.parent		= &clk_epll,
+	.id		= -1,
+	.set_parent	= s3c2443_setparent_esysclk,
+};
+
+/* uartclk
+ *
+ * UART baud-rate clock sourced from esysclk via a divisor
+*/
+
+static unsigned long s3c2443_getrate_uart(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+	div &= S3C2443_CLKDIV1_UARTDIV_MASK;
+	div >>= S3C2443_CLKDIV1_UARTDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+
+static int s3c2443_setrate_uart(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+	rate = s3c2443_roundrate_clksrc16(clk, rate);
+	rate = parent_rate / rate;
+
+	clkdivn &= ~S3C2443_CLKDIV1_UARTDIV_MASK;
+	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_UARTDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2443_CLKDIV1);
+	return 0;
+}
+
+static struct clk clk_uart = {
+	.name		= "uartclk",
+	.id		= -1,
+	.parent		= &clk_esysclk,
+	.get_rate	= s3c2443_getrate_uart,
+	.set_rate	= s3c2443_setrate_uart,
+	.round_rate	= s3c2443_roundrate_clksrc16,
+};
+
+/* hsspi
+ *
+ * high-speed spi clock, sourced from esysclk
+*/
+
+static unsigned long s3c2443_getrate_hsspi(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+	div &= S3C2443_CLKDIV1_HSSPIDIV_MASK;
+	div >>= S3C2443_CLKDIV1_HSSPIDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+
+static int s3c2443_setrate_hsspi(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+	rate = s3c2443_roundrate_clksrc4(clk, rate);
+	rate = parent_rate / rate;
+
+	clkdivn &= ~S3C2443_CLKDIV1_HSSPIDIV_MASK;
+	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_HSSPIDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2443_CLKDIV1);
+	return 0;
+}
+
+static struct clk clk_hsspi = {
+	.name		= "hsspi",
+	.id		= -1,
+	.parent		= &clk_esysclk,
+	.ctrlbit	= S3C2443_SCLKCON_HSSPICLK,
+	.enable		= s3c2443_clkcon_enable_s,
+	.get_rate	= s3c2443_getrate_hsspi,
+	.set_rate	= s3c2443_setrate_hsspi,
+	.round_rate	= s3c2443_roundrate_clksrc4,
+};
+
+/* usbhost
+ *
+ * usb host bus-clock, usually 48MHz to provide USB bus clock timing
+*/
+
+static unsigned long s3c2443_getrate_usbhost(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+	div &= S3C2443_CLKDIV1_USBHOSTDIV_MASK;
+	div >>= S3C2443_CLKDIV1_USBHOSTDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_usbhost(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+	rate = s3c2443_roundrate_clksrc4(clk, rate);
+	rate = parent_rate / rate;
+
+	clkdivn &= ~S3C2443_CLKDIV1_USBHOSTDIV_MASK;
+	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_USBHOSTDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2443_CLKDIV1);
+	return 0;
+}
+
+struct clk clk_usb_bus_host = {
+	.name		= "usb-bus-host-parent",
+	.id		= -1,
+	.parent		= &clk_esysclk,
+	.ctrlbit	= S3C2443_SCLKCON_USBHOST,
+	.enable		= s3c2443_clkcon_enable_s,
+	.get_rate	= s3c2443_getrate_usbhost,
+	.set_rate	= s3c2443_setrate_usbhost,
+	.round_rate	= s3c2443_roundrate_clksrc4,
+};
+
+/* clk_hsmcc_div
+ *
+ * this clock is sourced from epll, and is fed through a divider,
+ * to a mux controlled by sclkcon where either it or a extclk can
+ * be fed to the hsmmc block
+*/
+
+static unsigned long s3c2443_getrate_hsmmc_div(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+	div &= S3C2443_CLKDIV1_HSMMCDIV_MASK;
+	div >>= S3C2443_CLKDIV1_HSMMCDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_hsmmc_div(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+	rate = s3c2443_roundrate_clksrc4(clk, rate);
+	rate = parent_rate / rate;
+
+	clkdivn &= ~S3C2443_CLKDIV1_HSMMCDIV_MASK;
+	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_HSMMCDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2443_CLKDIV1);
+	return 0;
+}
+
+static struct clk clk_hsmmc_div = {
+	.name		= "hsmmc-div",
+	.id		= -1,
+	.parent		= &clk_esysclk,
+	.get_rate	= s3c2443_getrate_hsmmc_div,
+	.set_rate	= s3c2443_setrate_hsmmc_div,
+	.round_rate	= s3c2443_roundrate_clksrc4,
+};
+
+static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2443_SCLKCON);
+
+	clksrc &= ~(S3C2443_SCLKCON_HSMMCCLK_EXT |
+		    S3C2443_SCLKCON_HSMMCCLK_EPLL);
+
+	if (parent == &clk_epll)
+		clksrc |= S3C2443_SCLKCON_HSMMCCLK_EPLL;
+	else if (parent == &clk_ext)
+		clksrc |= S3C2443_SCLKCON_HSMMCCLK_EXT;
+	else
+		return -EINVAL;
+
+	if (clk->usage > 0) {
+		__raw_writel(clksrc, S3C2443_SCLKCON);
+	}
+
+	clk->parent = parent;
+	return 0;
+}
+
+static int s3c2443_enable_hsmmc(struct clk *clk, int enable)
+{
+	return s3c2443_setparent_hsmmc(clk, clk->parent);
+}
+
+static struct clk clk_hsmmc = {
+	.name		= "hsmmc-if",
+	.id		= -1,
+	.parent		= &clk_hsmmc_div,
+	.enable		= s3c2443_enable_hsmmc,
+	.set_parent	= s3c2443_setparent_hsmmc,
+};
+
+/* i2s_eplldiv
+ *
+ * this clock is the output from the i2s divisor of esysclk
+*/
+
+static unsigned long s3c2443_getrate_i2s_eplldiv(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+	div &= S3C2443_CLKDIV1_I2SDIV_MASK;
+	div >>= S3C2443_CLKDIV1_I2SDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_i2s_eplldiv(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+	rate = s3c2443_roundrate_clksrc16(clk, rate);
+	rate = parent_rate / rate;
+
+	clkdivn &= ~S3C2443_CLKDIV1_I2SDIV_MASK;
+	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_I2SDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2443_CLKDIV1);
+	return 0;
+}
+
+static struct clk clk_i2s_eplldiv = {
+	.name		= "i2s-eplldiv",
+	.id		= -1,
+	.parent		= &clk_esysclk,
+	.get_rate	= s3c2443_getrate_i2s_eplldiv,
+	.set_rate	= s3c2443_setrate_i2s_eplldiv,
+	.round_rate	= s3c2443_roundrate_clksrc16,
+};
+
+/* i2s-ref
+ *
+ * i2s bus reference clock, selectable from external, esysclk or epllref
+*/
+
+static int s3c2443_setparent_i2s(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+
+	clksrc &= ~S3C2443_CLKSRC_I2S_MASK;
+
+	if (parent == &clk_epllref)
+		clksrc |= S3C2443_CLKSRC_I2S_EPLLREF;
+	else if (parent == &clk_i2s_ext)
+		clksrc |= S3C2443_CLKSRC_I2S_EXT;
+	else if (parent != &clk_i2s_eplldiv)
+		return -EINVAL;
+
+	clk->parent = parent;
+	__raw_writel(clksrc, S3C2443_CLKSRC);
+
+	return 0;
+}
+
+static struct clk clk_i2s = {
+	.name		= "i2s-if",
+	.id		= -1,
+	.parent		= &clk_i2s_eplldiv,
+	.ctrlbit	= S3C2443_SCLKCON_I2SCLK,
+	.enable		= s3c2443_clkcon_enable_s,
+	.set_parent	= s3c2443_setparent_i2s,
+};
+
+/* cam-if
+ *
+ * camera interface bus-clock, divided down from esysclk
+*/
+
+static unsigned long s3c2443_getrate_cam(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+	div  &= S3C2443_CLKDIV1_CAMDIV_MASK;
+	div >>= S3C2443_CLKDIV1_CAMDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_cam(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdiv1 = __raw_readl(S3C2443_CLKDIV1);
+
+	rate = s3c2443_roundrate_clksrc16(clk, rate);
+	rate = parent_rate / rate;
+
+	clkdiv1 &= ~S3C2443_CLKDIV1_CAMDIV_MASK;
+	clkdiv1 |= (rate - 1) << S3C2443_CLKDIV1_CAMDIV_SHIFT;
+
+	__raw_writel(clkdiv1, S3C2443_CLKDIV1);
+	return 0;
+}
+
+static struct clk clk_cam = {
+	.name		= "camif-upll",		/* same as 2440 name */
+	.id		= -1,
+	.parent		= &clk_esysclk,
+	.ctrlbit	= S3C2443_SCLKCON_CAMCLK,
+	.enable		= s3c2443_clkcon_enable_s,
+	.get_rate	= s3c2443_getrate_cam,
+	.set_rate	= s3c2443_setrate_cam,
+	.round_rate	= s3c2443_roundrate_clksrc16,
+};
+
+/* display-if
+ *
+ * display interface clock, divided from esysclk
+*/
+
+static unsigned long s3c2443_getrate_display(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+	div &= S3C2443_CLKDIV1_DISPDIV_MASK;
+	div >>= S3C2443_CLKDIV1_DISPDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_display(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+	rate = s3c2443_roundrate_clksrc256(clk, rate);
+	rate = parent_rate / rate;
+
+	clkdivn &= ~S3C2443_CLKDIV1_UARTDIV_MASK;
+	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_UARTDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2443_CLKDIV1);
+	return 0;
+}
+
+static struct clk clk_display = {
+	.name		= "display-if",
+	.id		= -1,
+	.parent		= &clk_esysclk,
+	.ctrlbit	= S3C2443_SCLKCON_DISPCLK,
+	.enable		= s3c2443_clkcon_enable_s,
+	.get_rate	= s3c2443_getrate_display,
+	.set_rate	= s3c2443_setrate_display,
+	.round_rate	= s3c2443_roundrate_clksrc256,
+};
+
+/* standard clock definitions */
+
+static struct clk init_clocks_disable[] = {
+	{
+		.name		= "nand",
+		.id		= -1,
+		.parent		= &clk_h,
+	}, {
+		.name		= "sdi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_SDI,
+	}, {
+		.name		= "adc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_ADC,
+	}, {
+		.name		= "i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_IIC,
+	}, {
+		.name		= "iis",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_IIS,
+	}, {
+		.name		= "spi",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_SPI0,
+	}, {
+		.name		= "spi",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_SPI1,
+	}
+};
+
+static struct clk init_clocks[] = {
+	{
+		.name		= "dma",
+		.id		= 0,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA0,
+	}, {
+		.name		= "dma",
+		.id		= 1,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA1,
+	}, {
+		.name		= "dma",
+		.id		= 2,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA2,
+	}, {
+		.name		= "dma",
+		.id		= 3,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA3,
+	}, {
+		.name		= "dma",
+		.id		= 4,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA4,
+	}, {
+		.name		= "dma",
+		.id		= 5,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA5,
+	}, {
+		.name		= "lcd",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_LCDC,
+	}, {
+		.name		= "gpio",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_GPIO,
+	}, {
+		.name		= "usb-host",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_USBH,
+	}, {
+		.name		= "usb-device",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_USBD,
+	}, {
+		.name		= "timers",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_PWMT,
+	}, {
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_UART0,
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_UART1,
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_UART2,
+	}, {
+		.name		= "uart",
+		.id		= 3,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_UART3,
+	}, {
+		.name		= "rtc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_RTC,
+	}, {
+		.name		= "watchdog",
+		.id		= -1,
+		.parent		= &clk_p,
+		.ctrlbit	= S3C2443_PCLKCON_WDT,
+	}, {
+		.name		= "usb-bus-host",
+		.id		= -1,
+		.parent		= &clk_usb_bus_host,
+	}
+};
+
+/* clocks to add where we need to check their parentage */
+
+/* s3c2443_clk_initparents
+ *
+ * Initialise the parents for the clocks that we get at start-time
+*/
+
+static int __init clk_init_set_parent(struct clk *clk, struct clk *parent)
+{
+	printk(KERN_DEBUG "clock %s: parent %s\n", clk->name, parent->name);
+	return clk_set_parent(clk, parent);
+}
+
+static void __init s3c2443_clk_initparents(void)
+{
+	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+	struct clk *parent;
+
+	switch (clksrc & S3C2443_CLKSRC_EPLLREF_MASK) {
+	case S3C2443_CLKSRC_EPLLREF_EXTCLK:
+		parent = &clk_ext;
+		break;
+
+	case S3C2443_CLKSRC_EPLLREF_XTAL:
+	default:
+		parent = &clk_xtal;
+		break;
+
+	case S3C2443_CLKSRC_EPLLREF_MPLLREF:
+	case S3C2443_CLKSRC_EPLLREF_MPLLREF2:
+		parent = &clk_mpllref;
+		break;
+	}
+
+	clk_init_set_parent(&clk_epllref, parent);
+
+	switch (clksrc & S3C2443_CLKSRC_I2S_MASK) {
+	case S3C2443_CLKSRC_I2S_EXT:
+		parent = &clk_i2s_ext;
+		break;
+
+	case S3C2443_CLKSRC_I2S_EPLLDIV:
+	default:
+		parent = &clk_i2s_eplldiv;
+		break;
+
+	case S3C2443_CLKSRC_I2S_EPLLREF:
+	case S3C2443_CLKSRC_I2S_EPLLREF3:
+		parent = &clk_epllref;
+	}
+
+	clk_init_set_parent(&clk_i2s, &clk_epllref);
+
+	/* esysclk source */
+
+	parent = (clksrc & S3C2443_CLKSRC_ESYSCLK_EPLL) ?
+		&clk_epll : &clk_epllref;
+
+	clk_init_set_parent(&clk_esysclk, parent);
+
+	/* msysclk source */
+
+	if (clksrc & S3C2443_CLKSRC_MSYSCLK_MPLL) {
+		parent = &clk_mpll;
+	} else {
+		parent = (clksrc & S3C2443_CLKSRC_EXTCLK_DIV) ?
+			&clk_mdivclk : &clk_mpllref;
+	}
+
+	clk_init_set_parent(&clk_msysclk, parent);
+}
+
+/* armdiv divisor table */
+
+static unsigned int armdiv[16] = {
+	[S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 1,
+	[S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 2,
+	[S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 3,
+	[S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 4,
+	[S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 6,
+	[S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 8,
+	[S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 12,
+	[S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 16,
+};
+
+static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
+{
+	clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
+
+	return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
+}
+
+static inline unsigned long s3c2443_get_prediv(unsigned long clkcon0)
+{
+	clkcon0 &= S3C2443_CLKDIV0_PREDIV_MASK;
+	clkcon0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
+
+	return clkcon0 + 1;
+}
+
+/* clocks to add straight away */
+
+static struct clk *clks[] __initdata = {
+	&clk_ext,
+	&clk_epll,
+	&clk_usb_bus_host,
+	&clk_usb_bus,
+	&clk_esysclk,
+	&clk_epllref,
+	&clk_mpllref,
+	&clk_msysclk,
+	&clk_uart,
+	&clk_display,
+	&clk_cam,
+	&clk_i2s_eplldiv,
+	&clk_i2s,
+	&clk_hsspi,
+	&clk_hsmmc_div,
+	&clk_hsmmc,
+};
+
+void __init s3c2443_init_clocks(int xtal)
+{
+	unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
+	unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
+	unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+	unsigned long pll;
+	unsigned long fclk;
+	unsigned long hclk;
+	unsigned long pclk;
+	struct clk *clkp;
+	int ret;
+	int ptr;
+
+	pll = s3c2443_get_mpll(mpllcon, xtal);
+
+	fclk = pll / s3c2443_fclk_div(clkdiv0);
+	hclk = fclk / s3c2443_get_prediv(clkdiv0);
+	hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1);
+ 	pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
+
+	s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
+
+	printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
+	       (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
+	       print_mhz(pll), print_mhz(fclk),
+	       print_mhz(hclk), print_mhz(pclk));
+
+	s3c2443_clk_initparents();
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
+		clkp = clks[ptr];
+
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+	}
+
+	clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
+
+	clk_usb_bus.parent = &clk_usb_bus_host;
+
+	/* ensure usb bus clock is within correct rate of 48MHz */
+
+	if (clk_get_rate(&clk_usb_bus_host) != (48 * 1000 * 1000)) {
+		printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
+		clk_set_rate(&clk_usb_bus_host, 48*1000*1000);
+	}
+
+	printk("S3C2443: epll %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
+	       (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
+	       print_mhz(clk_get_rate(&clk_epll)),
+	       print_mhz(clk_get_rate(&clk_usb_bus)));
+
+	/* register clocks from clock array */
+
+	clkp = init_clocks;
+	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+	}
+
+	/* We must be careful disabling the clocks we are not intending to
+	 * be using at boot time, as subsytems such as the LCD which do
+	 * their own DMA requests to the bus can cause the system to lockup
+	 * if they where in the middle of requesting bus access.
+	 *
+	 * Disabling the LCD clock if the LCD is active is very dangerous,
+	 * and therefore the bootloader should be careful to not enable
+	 * the LCD clock if it is not needed.
+	*/
+
+	/* install (and disable) the clocks we do not need immediately */
+
+	clkp = init_clocks_disable;
+	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+
+		(clkp->enable)(clkp, 0);
+	}
+}
diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c
new file mode 100644
index 0000000..f70e8cc
--- /dev/null
+++ b/arch/arm/mach-s3c2443/dma.c
@@ -0,0 +1,180 @@
+/* linux/arch/arm/mach-s3c2443/dma.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2443 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+
+#include <asm/dma.h>
+#include <asm/arch/dma.h>
+#include <asm/io.h>
+
+#include <asm/plat-s3c24xx/dma.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-ac97.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-sdi.h>
+#include <asm/arch/regs-iis.h>
+#include <asm/arch/regs-spi.h>
+
+#define MAP(x) { \
+		[0]	= (x) | DMA_CH_VALID,	\
+		[1]	= (x) | DMA_CH_VALID,	\
+		[2]	= (x) | DMA_CH_VALID,	\
+		[3]	= (x) | DMA_CH_VALID,	\
+		[4]	= (x) | DMA_CH_VALID,	\
+		[5]     = (x) | DMA_CH_VALID,	\
+	}
+
+static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = {
+	[DMACH_XD0] = {
+		.name		= "xdreq0",
+		.channels	= MAP(S3C2443_DMAREQSEL_XDREQ0),
+	},
+	[DMACH_XD1] = {
+		.name		= "xdreq1",
+		.channels	= MAP(S3C2443_DMAREQSEL_XDREQ1),
+	},
+	[DMACH_SDI] = {
+		.name		= "sdi",
+		.channels	= MAP(S3C2443_DMAREQSEL_SDI),
+		.hw_addr.to	= S3C2410_PA_IIS + S3C2410_IISFIFO,
+		.hw_addr.from	= S3C2410_PA_IIS + S3C2410_IISFIFO,
+	},
+	[DMACH_SPI0] = {
+		.name		= "spi0",
+		.channels	= MAP(S3C2443_DMAREQSEL_SPI0TX),
+		.hw_addr.to	= S3C2410_PA_SPI + S3C2410_SPTDAT,
+		.hw_addr.from	= S3C2410_PA_SPI + S3C2410_SPRDAT,
+	},
+	[DMACH_SPI1] = {
+		.name		= "spi1",
+		.channels	= MAP(S3C2443_DMAREQSEL_SPI1TX),
+		.hw_addr.to	= S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
+		.hw_addr.from	= S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
+	},
+	[DMACH_UART0] = {
+		.name		= "uart0",
+		.channels	= MAP(S3C2443_DMAREQSEL_UART0_0),
+		.hw_addr.to	= S3C2410_PA_UART0 + S3C2410_UTXH,
+		.hw_addr.from	= S3C2410_PA_UART0 + S3C2410_URXH,
+	},
+	[DMACH_UART1] = {
+		.name		= "uart1",
+		.channels	= MAP(S3C2443_DMAREQSEL_UART1_0),
+		.hw_addr.to	= S3C2410_PA_UART1 + S3C2410_UTXH,
+		.hw_addr.from	= S3C2410_PA_UART1 + S3C2410_URXH,
+	},
+      	[DMACH_UART2] = {
+		.name		= "uart2",
+		.channels	= MAP(S3C2443_DMAREQSEL_UART2_0),
+		.hw_addr.to	= S3C2410_PA_UART2 + S3C2410_UTXH,
+		.hw_addr.from	= S3C2410_PA_UART2 + S3C2410_URXH,
+	},
+      	[DMACH_UART3] = {
+		.name		= "uart3",
+		.channels	= MAP(S3C2443_DMAREQSEL_UART3_0),
+		.hw_addr.to	= S3C2443_PA_UART3 + S3C2410_UTXH,
+		.hw_addr.from	= S3C2443_PA_UART3 + S3C2410_URXH,
+	},
+	[DMACH_UART0_SRC2] = {
+		.name		= "uart0",
+		.channels	= MAP(S3C2443_DMAREQSEL_UART0_1),
+		.hw_addr.to	= S3C2410_PA_UART0 + S3C2410_UTXH,
+		.hw_addr.from	= S3C2410_PA_UART0 + S3C2410_URXH,
+	},
+	[DMACH_UART1_SRC2] = {
+		.name		= "uart1",
+		.channels	= MAP(S3C2443_DMAREQSEL_UART1_1),
+		.hw_addr.to	= S3C2410_PA_UART1 + S3C2410_UTXH,
+		.hw_addr.from	= S3C2410_PA_UART1 + S3C2410_URXH,
+	},
+      	[DMACH_UART2_SRC2] = {
+		.name		= "uart2",
+		.channels	= MAP(S3C2443_DMAREQSEL_UART2_1),
+		.hw_addr.to	= S3C2410_PA_UART2 + S3C2410_UTXH,
+		.hw_addr.from	= S3C2410_PA_UART2 + S3C2410_URXH,
+	},
+      	[DMACH_UART3_SRC2] = {
+		.name		= "uart3",
+		.channels	= MAP(S3C2443_DMAREQSEL_UART3_1),
+		.hw_addr.to	= S3C2443_PA_UART3 + S3C2410_UTXH,
+		.hw_addr.from	= S3C2443_PA_UART3 + S3C2410_URXH,
+	},
+	[DMACH_TIMER] = {
+		.name		= "timer",
+		.channels	= MAP(S3C2443_DMAREQSEL_TIMER),
+	},
+	[DMACH_I2S_IN] = {
+		.name		= "i2s-sdi",
+		.channels	= MAP(S3C2443_DMAREQSEL_I2SRX),
+		.hw_addr.from	= S3C2410_PA_IIS + S3C2410_IISFIFO,
+	},
+	[DMACH_I2S_OUT] = {
+		.name		= "i2s-sdo",
+		.channels	= MAP(S3C2443_DMAREQSEL_I2STX),
+		.hw_addr.to	= S3C2410_PA_IIS + S3C2410_IISFIFO,
+	},
+	[DMACH_PCM_IN] = {
+		.name		= "pcm-in",
+		.channels	= MAP(S3C2443_DMAREQSEL_PCMIN),
+		.hw_addr.from	= S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
+	},
+	[DMACH_PCM_OUT] = {
+		.name		= "pcm-out",
+		.channels	= MAP(S3C2443_DMAREQSEL_PCMOUT),
+		.hw_addr.to	= S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
+	},
+	[DMACH_MIC_IN] = {
+		.name		= "mic-in",
+		.channels	= MAP(S3C2443_DMAREQSEL_MICIN),
+		.hw_addr.from	= S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
+	},
+};
+
+static void s3c2443_dma_select(struct s3c2410_dma_chan *chan,
+			       struct s3c24xx_dma_map *map)
+{
+	writel(map->channels[0] | S3C2443_DMAREQSEL_HW,
+	       chan->regs + S3C2443_DMA_DMAREQSEL);
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = {
+	.select		= s3c2443_dma_select,
+	.dcon_mask	= 0,
+	.map		= s3c2443_dma_mappings,
+	.map_size	= ARRAY_SIZE(s3c2443_dma_mappings),
+};
+
+static int s3c2443_dma_add(struct sys_device *sysdev)
+{
+	s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100);
+	return s3c24xx_dma_init_map(&s3c2443_dma_sel);
+}
+
+static struct sysdev_driver s3c2443_dma_driver = {
+	.add	= s3c2443_dma_add,
+};
+
+static int __init s3c2443_dma_init(void)
+{
+	return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_dma_driver);
+}
+
+arch_initcall(s3c2443_dma_init);
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
new file mode 100644
index 0000000..7a45b6d
--- /dev/null
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -0,0 +1,290 @@
+/* linux/arch/arm/mach-s3c2443/irq.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/ptrace.h>
+#include <linux/sysdev.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+#include <asm/arch/regs-irq.h>
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+#include <asm/plat-s3c24xx/irq.h>
+
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+
+static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
+{
+	unsigned int subsrc, submsk;
+	unsigned int end;
+	struct irq_desc *mydesc;
+
+	/* read the current pending interrupts, and the mask
+	 * for what it is available */
+
+	subsrc = __raw_readl(S3C2410_SUBSRCPND);
+	submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+	subsrc  &= ~submsk;
+	subsrc >>= (irq - S3C2410_IRQSUB(0));
+	subsrc  &= (1 << len)-1;
+
+	end = len + irq;
+	mydesc = irq_desc + irq;
+
+	for (; irq < end && subsrc; irq++) {
+		if (subsrc & 1)
+			desc_handle_irq(irq, mydesc);
+
+		mydesc++;
+		subsrc >>= 1;
+	}
+}
+
+/* WDT/AC97 sub interrupts */
+
+static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
+}
+
+#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
+#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+
+static void s3c2443_irq_wdtac97_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static void s3c2443_irq_wdtac97_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_WDTAC97);
+}
+
+static void s3c2443_irq_wdtac97_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static struct irq_chip s3c2443_irq_wdtac97 = {
+	.mask	    = s3c2443_irq_wdtac97_mask,
+	.unmask	    = s3c2443_irq_wdtac97_unmask,
+	.ack	    = s3c2443_irq_wdtac97_ack,
+};
+
+
+/* LCD sub interrupts */
+
+static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
+}
+
+#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
+#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+
+static void s3c2443_irq_lcd_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static void s3c2443_irq_lcd_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_LCD);
+}
+
+static void s3c2443_irq_lcd_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static struct irq_chip s3c2443_irq_lcd = {
+	.mask	    = s3c2443_irq_lcd_mask,
+	.unmask	    = s3c2443_irq_lcd_unmask,
+	.ack	    = s3c2443_irq_lcd_ack,
+};
+
+
+/* DMA sub interrupts */
+
+static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2443_DMA1, 6);
+}
+
+#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+
+
+static void s3c2443_irq_dma_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static void s3c2443_irq_dma_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_DMA);
+}
+
+static void s3c2443_irq_dma_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static struct irq_chip s3c2443_irq_dma = {
+	.mask	    = s3c2443_irq_dma_mask,
+	.unmask	    = s3c2443_irq_dma_unmask,
+	.ack	    = s3c2443_irq_dma_ack,
+};
+
+
+/* UART3 sub interrupts */
+
+static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2443_UART3, 3);
+}
+
+#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+#define SUBMSK_UART3	(0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+
+
+static void s3c2443_irq_uart3_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static void s3c2443_irq_uart3_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_UART3);
+}
+
+static void s3c2443_irq_uart3_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static struct irq_chip s3c2443_irq_uart3 = {
+	.mask	    = s3c2443_irq_uart3_mask,
+	.unmask	    = s3c2443_irq_uart3_unmask,
+	.ack	    = s3c2443_irq_uart3_ack,
+};
+
+
+/* CAM sub interrupts */
+
+static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
+}
+
+#define INTMSK_CAM	(1UL << (IRQ_CAM - IRQ_EINT0))
+#define SUBMSK_CAM	INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
+
+static void s3c2443_irq_cam_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_CAM, SUBMSK_CAM);
+}
+
+static void s3c2443_irq_cam_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_CAM);
+}
+
+static void s3c2443_irq_cam_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_CAM, SUBMSK_CAM);
+}
+
+static struct irq_chip s3c2443_irq_cam = {
+	.mask	    = s3c2443_irq_cam_mask,
+	.unmask	    = s3c2443_irq_cam_unmask,
+	.ack	    = s3c2443_irq_cam_ack,
+};
+
+/* IRQ initialisation code */
+
+static int __init s3c2443_add_sub(unsigned int base,
+				   void (*demux)(unsigned int,
+						 struct irq_desc *),
+				   struct irq_chip *chip,
+				   unsigned int start, unsigned int end)
+{
+	unsigned int irqno;
+
+	set_irq_chip(base, &s3c_irq_level_chip);
+	set_irq_handler(base, handle_level_irq);
+	set_irq_chained_handler(base, demux);
+
+	for (irqno = start; irqno <= end; irqno++) {
+		set_irq_chip(irqno, chip);
+		set_irq_handler(irqno, handle_level_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	return 0;
+}
+
+static int s3c2443_irq_add(struct sys_device *sysdev)
+{
+	printk("S3C2443: IRQ Support\n");
+
+	s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
+			IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
+
+	s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
+			IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
+
+	s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
+			&s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+
+	s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
+			&s3c2443_irq_uart3,
+			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+
+	s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
+			&s3c2443_irq_wdtac97,
+			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2443_irq_driver = {
+	.add		= s3c2443_irq_add,
+};
+
+static int s3c2443_irq_init(void)
+{
+	return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_irq_driver);
+}
+
+arch_initcall(s3c2443_irq_init);
+
diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c
new file mode 100644
index 0000000..e82aaff
--- /dev/null
+++ b/arch/arm/mach-s3c2443/mach-smdk2443.c
@@ -0,0 +1,137 @@
+/* linux/arch/arm/mach-s3c2443/mach-smdk2443.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.fluff.org/ben/smdk2443/
+ *
+ * Thanks to Samsung for the loan of an SMDK2443
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-lcd.h>
+
+#include <asm/arch/idle.h>
+#include <asm/arch/fb.h>
+
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/s3c2440.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+#include <asm/plat-s3c24xx/common-smdk.h>
+
+static struct map_desc smdk2443_iodesc[] __initdata = {
+	/* ISA IO Space map (memory space selected by A24) */
+
+	{
+		.virtual	= (u32)S3C24XX_VA_ISA_WORD,
+		.pfn		= __phys_to_pfn(S3C2410_CS2),
+		.length		= 0x10000,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+		.pfn		= __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+		.length		= SZ_4M,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (u32)S3C24XX_VA_ISA_BYTE,
+		.pfn		= __phys_to_pfn(S3C2410_CS2),
+		.length		= 0x10000,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+		.pfn		= __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+		.length		= SZ_4M,
+		.type		= MT_DEVICE,
+	}
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk2443_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+	/* IR port */
+	[2] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x43,
+		.ufcon	     = 0x51,
+	}
+};
+
+static struct platform_device *smdk2443_devices[] __initdata = {
+	&s3c_device_wdt,
+	&s3c_device_i2c,
+};
+
+static struct s3c24xx_board smdk2443_board __initdata = {
+	.devices       = smdk2443_devices,
+	.devices_count = ARRAY_SIZE(smdk2443_devices)
+};
+
+static void __init smdk2443_map_io(void)
+{
+	s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
+	s3c24xx_set_board(&smdk2443_board);
+}
+
+static void __init smdk2443_machine_init(void)
+{
+	smdk_machine_init();
+}
+
+MACHINE_START(SMDK2443, "SMDK2443")
+	/* Maintainer: Ben Dooks <ben@fluff.org> */
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+
+	.init_irq	= s3c24xx_init_irq,
+	.map_io		= smdk2443_map_io,
+	.init_machine	= smdk2443_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
new file mode 100644
index 0000000..11b1d0b
--- /dev/null
+++ b/arch/arm/mach-s3c2443/s3c2443.c
@@ -0,0 +1,97 @@
+/* linux/arch/arm/mach-s3c2443/s3c2443.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2443 Mobile CPU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-s3c2443-clock.h>
+#include <asm/arch/reset.h>
+
+#include <asm/plat-s3c24xx/s3c2443.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+static struct map_desc s3c2443_iodesc[] __initdata = {
+	IODESC_ENT(WATCHDOG),
+	IODESC_ENT(CLKPWR),
+	IODESC_ENT(TIMER),
+};
+
+struct sysdev_class s3c2443_sysclass = {
+	set_kset_name("s3c2443-core"),
+};
+
+static struct sys_device s3c2443_sysdev = {
+	.cls		= &s3c2443_sysclass,
+};
+
+static void s3c2443_hard_reset(void)
+{
+	__raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
+}
+
+int __init s3c2443_init(void)
+{
+	printk("S3C2443: Initialising architecture\n");
+
+	s3c24xx_reset_hook = s3c2443_hard_reset;
+
+	s3c_device_nand.name = "s3c2412-nand";
+
+	return sysdev_register(&s3c2443_sysdev);
+}
+
+void __init s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+	s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+}
+
+/* s3c2443_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+ */
+
+void __init s3c2443_map_io(struct map_desc *mach_desc, int mach_size)
+{
+	iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
+	iotable_init(mach_desc, mach_size);
+}
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2443 based system)
+ * as a driver which may support both 2443 and 2440 may try and use it.
+*/
+
+static int __init s3c2443_core_init(void)
+{
+	return sysdev_class_register(&s3c2443_sysclass);
+}
+
+core_initcall(s3c2443_core_init);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index aade2f7..e684e9b 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -171,8 +171,8 @@
 # ARM926T
 config CPU_ARM926T
 	bool "Support ARM926T processor"
-	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261
-	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261
+	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_NS9XXX
+	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_NS9XXX
 	select CPU_32v5
 	select CPU_ABRT_EV5TJ
 	select CPU_CACHE_VIVT
@@ -525,7 +525,7 @@
 	  of your chipset/board/processor.
 
 config CPU_HIGH_VECTOR
-	depends !MMU && CPU_CP15 && !CPU_ARM740T
+	depends on !MMU && CPU_CP15 && !CPU_ARM740T
 	bool "Select the High exception vector"
 	default n
 	help
@@ -609,3 +609,10 @@
 	  Forget about fast user space cmpxchg support.
 	  It is just not possible.
 
+config OUTER_CACHE
+	bool
+	default n
+
+config CACHE_L2X0
+	bool
+	select OUTER_CACHE
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index d2f5672..2f8b959 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -66,3 +66,5 @@
 obj-$(CONFIG_CPU_XSCALE)	+= proc-xscale.o
 obj-$(CONFIG_CPU_XSC3)		+= proc-xsc3.o
 obj-$(CONFIG_CPU_V6)		+= proc-v6.o
+
+obj-$(CONFIG_CACHE_L2X0)	+= cache-l2x0.o
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
new file mode 100644
index 0000000..08a36f1
--- /dev/null
+++ b/arch/arm/mm/cache-l2x0.c
@@ -0,0 +1,104 @@
+/*
+ * arch/arm/mm/cache-l2x0.c - L210/L220 cache controller support
+ *
+ * Copyright (C) 2007 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#define CACHE_LINE_SIZE		32
+
+static void __iomem *l2x0_base;
+
+static inline void sync_writel(unsigned long val, unsigned long reg,
+			       unsigned long complete_mask)
+{
+	writel(val, l2x0_base + reg);
+	/* wait for the operation to complete */
+	while (readl(l2x0_base + reg) & complete_mask)
+		;
+}
+
+static inline void cache_sync(void)
+{
+	sync_writel(0, L2X0_CACHE_SYNC, 1);
+}
+
+static inline void l2x0_inv_all(void)
+{
+	/* invalidate all ways */
+	sync_writel(0xff, L2X0_INV_WAY, 0xff);
+	cache_sync();
+}
+
+static void l2x0_inv_range(unsigned long start, unsigned long end)
+{
+	unsigned long addr;
+
+	start &= ~(CACHE_LINE_SIZE - 1);
+	for (addr = start; addr < end; addr += CACHE_LINE_SIZE)
+		sync_writel(addr, L2X0_INV_LINE_PA, 1);
+	cache_sync();
+}
+
+static void l2x0_clean_range(unsigned long start, unsigned long end)
+{
+	unsigned long addr;
+
+	start &= ~(CACHE_LINE_SIZE - 1);
+	for (addr = start; addr < end; addr += CACHE_LINE_SIZE)
+		sync_writel(addr, L2X0_CLEAN_LINE_PA, 1);
+	cache_sync();
+}
+
+static void l2x0_flush_range(unsigned long start, unsigned long end)
+{
+	unsigned long addr;
+
+	start &= ~(CACHE_LINE_SIZE - 1);
+	for (addr = start; addr < end; addr += CACHE_LINE_SIZE)
+		sync_writel(addr, L2X0_CLEAN_INV_LINE_PA, 1);
+	cache_sync();
+}
+
+void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
+{
+	__u32 aux;
+
+	l2x0_base = base;
+
+	/* disable L2X0 */
+	writel(0, l2x0_base + L2X0_CTRL);
+
+	aux = readl(l2x0_base + L2X0_AUX_CTRL);
+	aux &= aux_mask;
+	aux |= aux_val;
+	writel(aux, l2x0_base + L2X0_AUX_CTRL);
+
+	l2x0_inv_all();
+
+	/* enable L2X0 */
+	writel(1, l2x0_base + L2X0_CTRL);
+
+	outer_cache.inv_range = l2x0_inv_range;
+	outer_cache.clean_range = l2x0_clean_range;
+	outer_cache.flush_range = l2x0_flush_range;
+
+	printk(KERN_INFO "L2X0 cache controller enabled\n");
+}
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 6a9c362..1f9f94f 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -205,9 +205,10 @@
 	 * kernel direct-mapped region for device DMA.
 	 */
 	{
-		unsigned long kaddr = (unsigned long)page_address(page);
-		memset(page_address(page), 0, size);
-		dmac_flush_range(kaddr, kaddr + size);
+		void *ptr = page_address(page);
+		memset(ptr, 0, size);
+		dmac_flush_range(ptr, ptr + size);
+		outer_flush_range(__pa(ptr), __pa(ptr) + size);
 	}
 
 	/*
@@ -480,20 +481,24 @@
  * platforms with CONFIG_DMABOUNCE.
  * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
  */
-void consistent_sync(void *vaddr, size_t size, int direction)
+void consistent_sync(const void *start, size_t size, int direction)
 {
-	unsigned long start = (unsigned long)vaddr;
-	unsigned long end   = start + size;
+	const void *end = start + size;
+
+	BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(end - 1));
 
 	switch (direction) {
 	case DMA_FROM_DEVICE:		/* invalidate only */
 		dmac_inv_range(start, end);
+		outer_inv_range(__pa(start), __pa(end));
 		break;
 	case DMA_TO_DEVICE:		/* writeback only */
 		dmac_clean_range(start, end);
+		outer_clean_range(__pa(start), __pa(end));
 		break;
 	case DMA_BIDIRECTIONAL:		/* writeback and invalidate */
 		dmac_flush_range(start, end);
+		outer_flush_range(__pa(start), __pa(end));
 		break;
 	default:
 		BUG();
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 79e8002..9da43a0 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -19,7 +19,8 @@
 /*
  * We fork()ed a process, and we need a new context for the child
  * to run in.  We reserve version 0 for initial tasks so we will
- * always allocate an ASID.
+ * always allocate an ASID. The ASID 0 is reserved for the TTBR
+ * register changing sequence.
  */
 void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 {
@@ -38,8 +39,15 @@
 	 * If we've used up all our ASIDs, we need
 	 * to start a new version and flush the TLB.
 	 */
-	if ((asid & ~ASID_MASK) == 0)
+	if ((asid & ~ASID_MASK) == 0) {
+		asid = ++cpu_last_asid;
+		/* set the reserved ASID before flushing the TLB */
+		asm("mcr	p15, 0, %0, c13, c0, 1	@ set reserved context ID\n"
+		    :
+		    : "r" (0));
+		isb();
 		flush_tlb_all();
+	}
 
 	mm->context.id = asid;
 }
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index cf95c5d..44558d5 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -119,8 +119,6 @@
 		flush_cache_page(vma, addr, pfn);
 }
 
-void __flush_dcache_page(struct address_space *mapping, struct page *page);
-
 /*
  * Take care of architecture specific things when placing a new PTE into
  * a page table, or changing an existing PTE.  Basically, there are two
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 655c837..94fd4bf 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -49,8 +49,10 @@
 
 static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK;
 static unsigned int ecc_mask __initdata = 0;
+pgprot_t pgprot_user;
 pgprot_t pgprot_kernel;
 
+EXPORT_SYMBOL(pgprot_user);
 EXPORT_SYMBOL(pgprot_kernel);
 
 struct cachepolicy {
@@ -345,6 +347,7 @@
 		mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1);
 	}
 
+	pgprot_user   = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot);
 	pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
 				 L_PTE_DIRTY | L_PTE_WRITE |
 				 L_PTE_EXEC | kern_pgprot);
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 7b1843b..eb42e5b 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -14,10 +14,13 @@
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
 #include <asm/elf.h>
-#include <asm/hardware/arm_scu.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 
+#ifdef CONFIG_SMP
+#include <asm/hardware/arm_scu.h>
+#endif
+
 #include "proc-macros.S"
 
 #define D_CACHE_LINE_SIZE	32
@@ -30,6 +33,12 @@
 #define TTB_RGN_WT	(2 << 3)
 #define TTB_RGN_WB	(3 << 3)
 
+#ifndef CONFIG_SMP
+#define TTB_FLAGS	TTB_RGN_WBWA
+#else
+#define TTB_FLAGS	TTB_RGN_WBWA|TTB_S
+#endif
+
 ENTRY(cpu_v6_proc_init)
 	mov	pc, lr
 
@@ -92,9 +101,7 @@
 #ifdef CONFIG_MMU
 	mov	r2, #0
 	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
-#ifdef CONFIG_SMP
-	orr	r0, r0, #TTB_RGN_WBWA|TTB_S	@ mark PTWs shared, outer cacheable
-#endif
+	orr	r0, r0, #TTB_FLAGS
 	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
 	mcr	p15, 0, r2, c7, c10, 4		@ drain write buffer
 	mcr	p15, 0, r0, c2, c0, 0		@ set TTB 0
@@ -183,8 +190,7 @@
 	/* Set up the SCU on core 0 only */
 	mrc	p15, 0, r0, c0, c0, 5		@ CPU core number
 	ands	r0, r0, #15
-	moveq	r0, #0x10000000 @ SCU_BASE
-	orreq	r0, r0, #0x00100000
+	ldreq	r0, =SCU_BASE
 	ldreq	r5, [r0, #SCU_CTRL]
 	orreq	r5, r5, #1
 	streq	r5, [r0, #SCU_CTRL]
@@ -204,9 +210,7 @@
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I + D TLBs
 	mcr	p15, 0, r0, c2, c0, 2		@ TTB control register
-#ifdef CONFIG_SMP
-	orr	r4, r4, #TTB_RGN_WBWA|TTB_S	@ mark PTWs shared, outer cacheable
-#endif
+	orr	r4, r4, #TTB_FLAGS
 	mcr	p15, 0, r4, c2, c0, 1		@ load TTB1
 #endif /* CONFIG_MMU */
 	adr	r5, v6_crval
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 94a5845..d95921a 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -5,23 +5,23 @@
  * Current Maintainer: Lennert Buytenhek <buytenh@wantstofly.org>
  *
  * Copyright 2004 (C) Intel Corp.
- * Copyright 2005 (c) MontaVista Software, Inc.
+ * Copyright 2005 (C) MontaVista Software, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * MMU functions for the Intel XScale3 Core (XSC3).  The XSC3 core is an
- * extension to Intel's original XScale core that adds the following
+ * MMU functions for the Intel XScale3 Core (XSC3).  The XSC3 core is
+ * an extension to Intel's original XScale core that adds the following
  * features:
  *
  * - ARMv6 Supersections
  * - Low Locality Reference pages (replaces mini-cache)
  * - 36-bit addressing
  * - L2 cache
- * - Cache-coherency if chipset supports it
+ * - Cache coherency if chipset supports it
  *
- * Based on orignal XScale code by Nicolas Pitre
+ * Based on original XScale code by Nicolas Pitre.
  */
 
 #include <linux/linkage.h>
@@ -42,12 +42,12 @@
 #define MAX_AREA_SIZE	32768
 
 /*
- * The cache line size of the I and D cache.
+ * The cache line size of the L1 I, L1 D and unified L2 cache.
  */
 #define CACHELINESIZE	32
 
 /*
- * The size of the data cache.
+ * The size of the L1 D cache.
  */
 #define CACHESIZE	32768
 
@@ -57,9 +57,9 @@
 #define L2_CACHE_ENABLE	1
 
 /*
- * This macro is used to wait for a CP15 write and is needed
- * when we have to ensure that the last operation to the co-pro
- * was completed before continuing with operation.
+ * This macro is used to wait for a CP15 write and is needed when we
+ * have to ensure that the last operation to the coprocessor was
+ * completed before continuing with operation.
  */
 	.macro	cpwait_ret, lr, rd
 	mrc	p15, 0, \rd, c2, c0, 0		@ arbitrary read of cp15
@@ -68,13 +68,13 @@
 	.endm
 
 /*
- * This macro cleans & invalidates the entire xsc3 dcache by set & way.
+ * This macro cleans and invalidates the entire L1 D cache.
  */
 
  	.macro  clean_d_cache rd, rs
 	mov	\rd, #0x1f00
 	orr	\rd, \rd, #0x00e0
-1:	mcr	p15, 0, \rd, c7, c14, 2		@ clean/inv set/way
+1:	mcr	p15, 0, \rd, c7, c14, 2		@ clean/invalidate L1 D line
 	adds	\rd, \rd, #0x40000000
 	bcc	1b
 	subs	\rd, \rd, #0x20
@@ -119,15 +119,15 @@
 	mov	r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
 	msr	cpsr_c, r1			@ reset CPSR
 	mrc	p15, 0, r1, c1, c0, 0		@ ctrl register
-	bic	r1, r1, #0x0086			@ ........B....CA.
 	bic	r1, r1, #0x3900			@ ..VIZ..S........
+	bic	r1, r1, #0x0086			@ ........B....CA.
 	mcr	p15, 0, r1, c1, c0, 0		@ ctrl register
-	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches & BTB
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate L1 caches and BTB
 	bic	r1, r1, #0x0001			@ ...............M
 	mcr	p15, 0, r1, c1, c0, 0		@ ctrl register
 	@ CAUTION: MMU turned off from this point.  We count on the pipeline
 	@ already containing those two last instructions to survive.
-	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I and D TLBs
 	mov	pc, r0
 
 /*
@@ -139,14 +139,12 @@
  *
  * XScale supports clock switching, but using idle mode support
  * allows external hardware to react to system state changes.
-
- MMG: Come back to this one.
  */
 	.align	5
 
 ENTRY(cpu_xsc3_do_idle)
 	mov	r0, #1
-	mcr	p14, 0, r0, c7, c0, 0		@ Go to IDLE
+	mcr	p14, 0, r0, c7, c0, 0		@ go to idle
 	mov	pc, lr
 
 /* ================================= CACHE ================================ */
@@ -171,9 +169,9 @@
 __flush_whole_cache:
 	clean_d_cache r0, r1
 	tst	r2, #VM_EXEC
-	mcrne	p15, 0, ip, c7, c5, 0		@ Invalidate I cache & BTB
-	mcrne	p15, 0, ip, c7, c10, 4		@ Drain Write Buffer
-	mcrne	p15, 0, ip, c7, c5, 4		@ Prefetch Flush
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate L1 I cache and BTB
+	mcrne	p15, 0, ip, c7, c10, 4		@ data write barrier
+	mcrne	p15, 0, ip, c7, c5, 4		@ prefetch flush
 	mov	pc, lr
 
 /*
@@ -194,21 +192,21 @@
 	bhs	__flush_whole_cache
 
 1:	tst	r2, #VM_EXEC
-	mcrne	p15, 0, r0, c7, c5, 1		@ Invalidate I cache line
-	mcr	p15, 0, r0, c7, c14, 1		@ Clean/invalidate D cache line
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate L1 I line
+	mcr	p15, 0, r0, c7, c14, 1		@ clean/invalidate L1 D line
 	add	r0, r0, #CACHELINESIZE
 	cmp	r0, r1
 	blo	1b
 	tst	r2, #VM_EXEC
-	mcrne	p15, 0, ip, c7, c5, 6		@ Invalidate BTB
-	mcrne	p15, 0, ip, c7, c10, 4		@ Drain Write Buffer
-	mcrne	p15, 0, ip, c7, c5, 4		@ Prefetch Flush
+	mcrne	p15, 0, ip, c7, c5, 6		@ invalidate BTB
+	mcrne	p15, 0, ip, c7, c10, 4		@ data write barrier
+	mcrne	p15, 0, ip, c7, c5, 4		@ prefetch flush
 	mov	pc, lr
 
 /*
  *	coherent_kern_range(start, end)
  *
- *	Ensure coherency between the Icache and the Dcache in the
+ *	Ensure coherency between the I cache and the D cache in the
  *	region described by start.  If you have non-snooping
  *	Harvard caches, you need to implement this function.
  *
@@ -222,34 +220,34 @@
 /* FALLTHROUGH */
 ENTRY(xsc3_coherent_user_range)
 	bic	r0, r0, #CACHELINESIZE - 1
-1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean L1 D line
 	add	r0, r0, #CACHELINESIZE
 	cmp	r0, r1
 	blo	1b
 	mov	r0, #0
-	mcr	p15, 0, r0, c7, c5, 0		@ Invalidate I cache & BTB
-	mcr	p15, 0, r0, c7, c10, 4		@ Drain Write Buffer
-	mcr	p15, 0, r0, c7, c5, 4		@ Prefetch Flush
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate L1 I cache and BTB
+	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
+	mcr	p15, 0, r0, c7, c5, 4		@ prefetch flush
 	mov	pc, lr
 
 /*
  *	flush_kern_dcache_page(void *page)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
- *	the I cache
+ *	the I cache.
  *
  *	- addr	- page aligned address
  */
 ENTRY(xsc3_flush_kern_dcache_page)
 	add	r1, r0, #PAGE_SZ
-1:	mcr	p15, 0, r0, c7, c14, 1		@ Clean/Invalidate D Cache line
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean/invalidate L1 D line
 	add	r0, r0, #CACHELINESIZE
 	cmp	r0, r1
 	blo	1b
 	mov	r0, #0
-	mcr	p15, 0, r0, c7, c5, 0		@ Invalidate I cache & BTB
-	mcr	p15, 0, r0, c7, c10, 4		@ Drain Write Buffer
-	mcr	p15, 0, r0, c7, c5, 4		@ Prefetch Flush
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate L1 I cache and BTB
+	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
+	mcr	p15, 0, r0, c7, c5, 4		@ prefetch flush
 	mov	pc, lr
 
 /*
@@ -266,17 +264,17 @@
 ENTRY(xsc3_dma_inv_range)
 	tst	r0, #CACHELINESIZE - 1
 	bic	r0, r0, #CACHELINESIZE - 1
-	mcrne	p15, 0, r0, c7, c10, 1		@ clean L1 D entry
-	mcrne	p15, 1, r0, c7, c11, 1		@ clean L2 D entry
+	mcrne	p15, 0, r0, c7, c10, 1		@ clean L1 D line
+	mcrne	p15, 1, r0, c7, c11, 1		@ clean L2 line
 	tst	r1, #CACHELINESIZE - 1
-	mcrne	p15, 0, r1, c7, c10, 1		@ clean L1 D entry
-	mcrne	p15, 1, r1, c7, c11, 1		@ clean L2 D entry
-1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate L1 D entry
-	mcr	p15, 1, r0, c7, c7, 1		@ Invalidate L2 D cache line
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean L1 D line
+	mcrne	p15, 1, r1, c7, c11, 1		@ clean L2 line
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate L1 D line
+	mcr	p15, 1, r0, c7, c7, 1		@ invalidate L2 line
 	add	r0, r0, #CACHELINESIZE
 	cmp	r0, r1
 	blo	1b
-	mcr	p15, 0, r0, c7, c10, 4		@ Drain Write Buffer
+	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
 	mov	pc, lr
 
 /*
@@ -289,12 +287,12 @@
  */
 ENTRY(xsc3_dma_clean_range)
 	bic	r0, r0, #CACHELINESIZE - 1
-1:	mcr	p15, 0, r0, c7, c10, 1		@ clean L1 D entry
-	mcr	p15, 1, r0, c7, c11, 1		@ clean L2 D entry
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean L1 D line
+	mcr	p15, 1, r0, c7, c11, 1		@ clean L2 line
 	add	r0, r0, #CACHELINESIZE
 	cmp	r0, r1
 	blo	1b
-	mcr	p15, 0, r0, c7, c10, 4		@ Drain Write Buffer
+	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
 	mov	pc, lr
 
 /*
@@ -307,13 +305,13 @@
  */
 ENTRY(xsc3_dma_flush_range)
 	bic	r0, r0, #CACHELINESIZE - 1
-1:	mcr	p15, 0, r0, c7, c14, 1	@ Clean/invalidate L1 D cache line
-	mcr	p15, 1, r0, c7, c11, 1	@ Clean L2 D cache line
-	mcr	p15, 1, r0, c7, c7, 1	@ Invalidate L2 D cache line
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean/invalidate L1 D line
+	mcr	p15, 1, r0, c7, c11, 1		@ clean L2 line
+	mcr	p15, 1, r0, c7, c7, 1		@ invalidate L2 line
 	add	r0, r0, #CACHELINESIZE
 	cmp	r0, r1
 	blo	1b
-	mcr	p15, 0, r0, c7, c10, 4		@ Drain Write Buffer
+	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
 	mov	pc, lr
 
 ENTRY(xsc3_cache_fns)
@@ -328,7 +326,7 @@
 	.long	xsc3_dma_flush_range
 
 ENTRY(cpu_xsc3_dcache_clean_area)
-1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean L1 D line
 	add	r0, r0, #CACHELINESIZE
 	subs	r1, r1, #CACHELINESIZE
 	bhi	1b
@@ -346,14 +344,14 @@
 	.align	5
 ENTRY(cpu_xsc3_switch_mm)
 	clean_d_cache r1, r2
-	mcr	p15, 0, ip, c7, c5, 0		@ Invalidate I cache & BTB
-	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write Buffer
-	mcr	p15, 0, ip, c7, c5, 4		@ Prefetch Flush
+	mcr	p15, 0, ip, c7, c5, 0		@ invalidate L1 I cache and BTB
+	mcr	p15, 0, ip, c7, c10, 4		@ data write barrier
+	mcr	p15, 0, ip, c7, c5, 4		@ prefetch flush
 #ifdef L2_CACHE_ENABLE
 	orr	r0, r0, #0x18			@ cache the page table in L2
 #endif
 	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
-	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I and D TLBs
 	cpwait_ret lr, ip
 
 /*
@@ -366,34 +364,34 @@
 ENTRY(cpu_xsc3_set_pte_ext)
 	str	r1, [r0], #-2048		@ linux version
 
-	bic	r2, r1, #0xff0			@ Keep C, B bits
+	bic	r2, r1, #0xff0			@ keep C, B bits
 	orr	r2, r2, #PTE_TYPE_EXT		@ extended page
-	tst	r1, #L_PTE_SHARED		@ Shared?
+	tst	r1, #L_PTE_SHARED		@ shared?
 	orrne	r2, r2, #0x200
 
 	eor	r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
 
-	tst	r3, #L_PTE_USER			@ User?
+	tst	r3, #L_PTE_USER			@ user?
 	orrne	r2, r2, #PTE_EXT_AP_URO_SRW	@ yes -> user r/o, system r/w
 
-	tst	r3, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
+	tst	r3, #L_PTE_WRITE | L_PTE_DIRTY	@ write and dirty?
 	orreq	r2, r2, #PTE_EXT_AP_UNO_SRW	@ yes -> user n/a, system r/w
 						@ combined with user -> user r/w
 
 #if L2_CACHE_ENABLE
-	@ If its cacheable it needs to be in L2 also.
+	@ If it's cacheable, it needs to be in L2 also.
 	eor	ip, r1, #L_PTE_CACHEABLE
 	tst	ip, #L_PTE_CACHEABLE
 	orreq	r2, r2, #PTE_EXT_TEX(0x5)
 #endif
 
-	tst	r3, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
+	tst	r3, #L_PTE_PRESENT | L_PTE_YOUNG	@ present and young?
 	movne	r2, #0				@ no -> fault
 
 	str	r2, [r0]			@ hardware version
 	mov	ip, #0
-	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line mcr
-	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write Buffer
+	mcr	p15, 0, r0, c7, c10, 1		@ clean L1 D line
+	mcr	p15, 0, ip, c7, c10, 4		@ data write barrier
 	mov	pc, lr
 
 	.ltorg
@@ -406,17 +404,18 @@
 __xsc3_setup:
 	mov	r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
 	msr	cpsr_c, r0
-	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I, D caches & BTB
-	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write Buffer
-	mcr	p15, 0, ip, c7, c5, 4		@ Prefetch Flush
-	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I, D TLBs
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate L1 caches and BTB
+	mcr	p15, 0, ip, c7, c10, 4		@ data write barrier
+	mcr	p15, 0, ip, c7, c5, 4		@ prefetch flush
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I and D TLBs
 #if L2_CACHE_ENABLE
 	orr	r4, r4, #0x18			@ cache the page table in L2
 #endif
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
-	mov	r0, #1				@ Allow access to CP0 and CP13
-	orr	r0, r0, #1 << 13		@ Its undefined whether this
-	mcr	p15, 0, r0, c15, c1, 0		@ affects USR or SVC modes
+
+	mov	r0, #0				@ don't allow CP access
+	mcr	p15, 0, r0, c15, c1, 0		@ write CP access register
+
 	mrc	p15, 0, r0, c1, c0, 1		@ get auxiliary control reg
 	and	r0, r0, #2			@ preserve bit P bit setting
 #if L2_CACHE_ENABLE
@@ -427,9 +426,9 @@
 	adr	r5, xsc3_crval
 	ldmia	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0, 0		@ get control register
-	bic	r0, r0, r5			@ .... .... .... ..A.
-	orr	r0, r0, r6			@ .... .... .... .C.M
-	orr	r0, r0, #0x00000800		@ ..VI Z..S .... ....
+	bic	r0, r0, r5			@ ..V. ..R. .... ..A.
+	orr	r0, r0, r6			@ ..VI Z..S .... .C.M (mmu)
+						@ ...I Z..S .... .... (uc)
 #if L2_CACHE_ENABLE
 	orr 	r0, r0, #0x04000000		@ L2 enable
 #endif
@@ -439,7 +438,7 @@
 
 	.type	xsc3_crval, #object
 xsc3_crval:
-	crval	clear=0x04003b02, mmuset=0x00003105, ucset=0x00001100
+	crval	clear=0x04002202, mmuset=0x00003905, ucset=0x00001900
 
 	__INITDATA
 
@@ -474,7 +473,7 @@
 
 	.type	cpu_xsc3_name, #object
 cpu_xsc3_name:
-	.asciz	"XScale-Core3"
+	.asciz	"XScale-V3 based processor"
 	.size	cpu_xsc3_name, . - cpu_xsc3_name
 
 	.align
@@ -490,7 +489,7 @@
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
-	.long   PMD_TYPE_SECT | \
+	.long	PMD_TYPE_SECT | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
 	b	__xsc3_setup
diff --git a/arch/arm/mm/tlb-v6.S b/arch/arm/mm/tlb-v6.S
index fd6adde..20f84bb 100644
--- a/arch/arm/mm/tlb-v6.S
+++ b/arch/arm/mm/tlb-v6.S
@@ -53,6 +53,8 @@
 	add	r0, r0, #PAGE_SZ
 	cmp	r0, r1
 	blo	1b
+	mcr	p15, 0, ip, c7, c5, 6		@ flush BTAC/BTB
+	mcr	p15, 0, ip, c7, c10, 4		@ data synchronization barrier
 	mov	pc, lr
 
 /*
@@ -80,7 +82,9 @@
 	add	r0, r0, #PAGE_SZ
 	cmp	r0, r1
 	blo	1b
+	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
 	mcr	p15, 0, r2, c7, c10, 4		@ data synchronization barrier
+	mcr	p15, 0, r2, c7, c5, 4		@ prefetch flush
 	mov	pc, lr
 
 	.section ".text.init", #alloc, #execinstr
diff --git a/arch/arm/oprofile/Kconfig b/arch/arm/oprofile/Kconfig
index 19d3773..afd93ad 100644
--- a/arch/arm/oprofile/Kconfig
+++ b/arch/arm/oprofile/Kconfig
@@ -19,5 +19,24 @@
 
 	  If unsure, say N.
 
+if OPROFILE
+
+config OPROFILE_ARMV6
+	bool
+	depends on CPU_V6 && !SMP
+	default y
+	select OPROFILE_ARM11_CORE
+
+config OPROFILE_MPCORE
+	bool
+	depends on CPU_V6 && SMP
+	default y
+	select OPROFILE_ARM11_CORE
+
+config OPROFILE_ARM11_CORE
+	bool
+
+endif
+
 endmenu
 
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
index 6a94e54..e61d0cc 100644
--- a/arch/arm/oprofile/Makefile
+++ b/arch/arm/oprofile/Makefile
@@ -8,4 +8,6 @@
 
 oprofile-y				:= $(DRIVER_OBJS) common.o backtrace.o
 oprofile-$(CONFIG_CPU_XSCALE)		+= op_model_xscale.o
-
+oprofile-$(CONFIG_OPROFILE_ARM11_CORE)	+= op_model_arm11_core.o
+oprofile-$(CONFIG_OPROFILE_ARMV6)	+= op_model_v6.o
+oprofile-$(CONFIG_OPROFILE_MPCORE)	+= op_model_mpcore.o
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
index 6f83335..0a007b9 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -135,6 +135,14 @@
 	spec = &op_xscale_spec;
 #endif
 
+#ifdef CONFIG_OPROFILE_ARMV6
+	spec = &op_armv6_spec;
+#endif
+
+#ifdef CONFIG_OPROFILE_MPCORE
+	spec = &op_mpcore_spec;
+#endif
+
 	if (spec) {
 		ret = spec->init();
 		if (ret < 0)
diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h
index 38c6ad1..4899c62 100644
--- a/arch/arm/oprofile/op_arm_model.h
+++ b/arch/arm/oprofile/op_arm_model.h
@@ -24,6 +24,9 @@
 extern struct op_arm_model_spec op_xscale_spec;
 #endif
 
+extern struct op_arm_model_spec op_armv6_spec;
+extern struct op_arm_model_spec op_mpcore_spec;
+
 extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth);
 
 extern int __init op_arm_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
diff --git a/arch/arm/oprofile/op_model_arm11_core.c b/arch/arm/oprofile/op_model_arm11_core.c
new file mode 100644
index 0000000..ad80752
--- /dev/null
+++ b/arch/arm/oprofile/op_model_arm11_core.c
@@ -0,0 +1,162 @@
+/**
+ * @file op_model_arm11_core.c
+ * ARM11 Event Monitor Driver
+ * @remark Copyright 2004 ARM SMP Development Team
+ */
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/smp.h>
+
+#include "op_counter.h"
+#include "op_arm_model.h"
+#include "op_model_arm11_core.h"
+
+/*
+ * ARM11 PMU support
+ */
+static inline void arm11_write_pmnc(u32 val)
+{
+	/* upper 4bits and 7, 11 are write-as-0 */
+	val &= 0x0ffff77f;
+	asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r" (val));
+}
+
+static inline u32 arm11_read_pmnc(void)
+{
+	u32 val;
+	asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r" (val));
+	return val;
+}
+
+static void arm11_reset_counter(unsigned int cnt)
+{
+	u32 val = -(u32)counter_config[CPU_COUNTER(smp_processor_id(), cnt)].count;
+	switch (cnt) {
+	case CCNT:
+		asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r" (val));
+		break;
+
+	case PMN0:
+		asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r" (val));
+		break;
+
+	case PMN1:
+		asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r" (val));
+		break;
+	}
+}
+
+int arm11_setup_pmu(void)
+{
+	unsigned int cnt;
+	u32 pmnc;
+
+	if (arm11_read_pmnc() & PMCR_E) {
+		printk(KERN_ERR "oprofile: CPU%u PMU still enabled when setup new event counter.\n", smp_processor_id());
+		return -EBUSY;
+	}
+
+	/* initialize PMNC, reset overflow, D bit, C bit and P bit. */
+	arm11_write_pmnc(PMCR_OFL_PMN0 | PMCR_OFL_PMN1 | PMCR_OFL_CCNT |
+			 PMCR_C | PMCR_P);
+
+	for (pmnc = 0, cnt = PMN0; cnt <= CCNT; cnt++) {
+		unsigned long event;
+
+		if (!counter_config[CPU_COUNTER(smp_processor_id(), cnt)].enabled)
+			continue;
+
+		event = counter_config[CPU_COUNTER(smp_processor_id(), cnt)].event & 255;
+
+		/*
+		 * Set event (if destined for PMNx counters)
+		 */
+		if (cnt == PMN0) {
+			pmnc |= event << 20;
+		} else if (cnt == PMN1) {
+			pmnc |= event << 12;
+		}
+
+		/*
+		 * We don't need to set the event if it's a cycle count
+		 * Enable interrupt for this counter
+		 */
+		pmnc |= PMCR_IEN_PMN0 << cnt;
+		arm11_reset_counter(cnt);
+	}
+	arm11_write_pmnc(pmnc);
+
+	return 0;
+}
+
+int arm11_start_pmu(void)
+{
+	arm11_write_pmnc(arm11_read_pmnc() | PMCR_E);
+	return 0;
+}
+
+int arm11_stop_pmu(void)
+{
+	unsigned int cnt;
+
+	arm11_write_pmnc(arm11_read_pmnc() & ~PMCR_E);
+
+	for (cnt = PMN0; cnt <= CCNT; cnt++)
+		arm11_reset_counter(cnt);
+
+	return 0;
+}
+
+/*
+ * CPU counters' IRQ handler (one IRQ per CPU)
+ */
+static irqreturn_t arm11_pmu_interrupt(int irq, void *arg)
+{
+	struct pt_regs *regs = get_irq_regs();
+	unsigned int cnt;
+	u32 pmnc;
+
+	pmnc = arm11_read_pmnc();
+
+	for (cnt = PMN0; cnt <= CCNT; cnt++) {
+		if ((pmnc & (PMCR_OFL_PMN0 << cnt)) && (pmnc & (PMCR_IEN_PMN0 << cnt))) {
+			arm11_reset_counter(cnt);
+			oprofile_add_sample(regs, CPU_COUNTER(smp_processor_id(), cnt));
+		}
+	}
+	/* Clear counter flag(s) */
+	arm11_write_pmnc(pmnc);
+	return IRQ_HANDLED;
+}
+
+int arm11_request_interrupts(int *irqs, int nr)
+{
+	unsigned int i;
+	int ret = 0;
+
+	for(i = 0; i < nr; i++) {
+		ret = request_irq(irqs[i], arm11_pmu_interrupt, IRQF_DISABLED, "CP15 PMU", NULL);
+		if (ret != 0) {
+			printk(KERN_ERR "oprofile: unable to request IRQ%u for MPCORE-EM\n",
+			       irqs[i]);
+			break;
+		}
+	}
+
+	if (i != nr)
+		while (i-- != 0)
+			free_irq(irqs[i], NULL);
+
+	return ret;
+}
+
+void arm11_release_interrupts(int *irqs, int nr)
+{
+	unsigned int i;
+
+	for (i = 0; i < nr; i++)
+		free_irq(irqs[i], NULL);
+}
diff --git a/arch/arm/oprofile/op_model_arm11_core.h b/arch/arm/oprofile/op_model_arm11_core.h
new file mode 100644
index 0000000..6f8538e
--- /dev/null
+++ b/arch/arm/oprofile/op_model_arm11_core.h
@@ -0,0 +1,45 @@
+/**
+ * @file op_model_arm11_core.h
+ * ARM11 Event Monitor Driver
+ * @remark Copyright 2004 ARM SMP Development Team
+ * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
+ * @remark Copyright 2000-2004 MontaVista Software Inc
+ * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
+ * @remark Copyright 2004 Intel Corporation
+ * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
+ * @remark Copyright 2004 Oprofile Authors
+ *
+ * @remark Read the file COPYING
+ *
+ * @author Zwane Mwaikambo
+ */
+#ifndef OP_MODEL_ARM11_CORE_H
+#define OP_MODEL_ARM11_CORE_H
+
+/*
+ * Per-CPU PMCR
+ */
+#define PMCR_E		(1 << 0)	/* Enable */
+#define PMCR_P		(1 << 1)	/* Count reset */
+#define PMCR_C		(1 << 2)	/* Cycle counter reset */
+#define PMCR_D		(1 << 3)	/* Cycle counter counts every 64th cpu cycle */
+#define PMCR_IEN_PMN0	(1 << 4)	/* Interrupt enable count reg 0 */
+#define PMCR_IEN_PMN1	(1 << 5)	/* Interrupt enable count reg 1 */
+#define PMCR_IEN_CCNT	(1 << 6)	/* Interrupt enable cycle counter */
+#define PMCR_OFL_PMN0	(1 << 8)	/* Count reg 0 overflow */
+#define PMCR_OFL_PMN1	(1 << 9)	/* Count reg 1 overflow */
+#define PMCR_OFL_CCNT	(1 << 10)	/* Cycle counter overflow */
+
+#define PMN0 0
+#define PMN1 1
+#define CCNT 2
+
+#define CPU_COUNTER(cpu, counter)	((cpu) * 3 + (counter))
+
+int arm11_setup_pmu(void);
+int arm11_start_pmu(void);
+int arm11_stop_pmu(void);
+int arm11_request_interrupts(int *, int);
+void arm11_release_interrupts(int *, int);
+
+#endif
diff --git a/arch/arm/oprofile/op_model_mpcore.c b/arch/arm/oprofile/op_model_mpcore.c
new file mode 100644
index 0000000..8985007
--- /dev/null
+++ b/arch/arm/oprofile/op_model_mpcore.c
@@ -0,0 +1,296 @@
+/**
+ * @file op_model_mpcore.c
+ * MPCORE Event Monitor Driver
+ * @remark Copyright 2004 ARM SMP Development Team
+ * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
+ * @remark Copyright 2000-2004 MontaVista Software Inc
+ * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
+ * @remark Copyright 2004 Intel Corporation
+ * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
+ * @remark Copyright 2004 Oprofile Authors
+ *
+ * @remark Read the file COPYING
+ *
+ * @author Zwane Mwaikambo
+ *
+ *  Counters:
+ *    0: PMN0 on CPU0, per-cpu configurable event counter
+ *    1: PMN1 on CPU0, per-cpu configurable event counter
+ *    2: CCNT on CPU0
+ *    3: PMN0 on CPU1
+ *    4: PMN1 on CPU1
+ *    5: CCNT on CPU1
+ *    6: PMN0 on CPU1
+ *    7: PMN1 on CPU1
+ *    8: CCNT on CPU1
+ *    9: PMN0 on CPU1
+ *   10: PMN1 on CPU1
+ *   11: CCNT on CPU1
+ *   12-19: configurable SCU event counters
+ */
+
+/* #define DEBUG */
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/hardware.h>
+#include <asm/system.h>
+
+#include "op_counter.h"
+#include "op_arm_model.h"
+#include "op_model_arm11_core.h"
+#include "op_model_mpcore.h"
+
+/*
+ * MPCore SCU event monitor support
+ */
+#define SCU_EVENTMONITORS_VA_BASE __io_address(REALVIEW_MPCORE_SCU_BASE + 0x10)
+
+/*
+ * Bitmask of used SCU counters
+ */
+static unsigned int scu_em_used;
+
+/*
+ * 2 helper fns take a counter number from 0-7 (not the userspace-visible counter number)
+ */
+static inline void scu_reset_counter(struct eventmonitor __iomem *emc, unsigned int n)
+{
+	writel(-(u32)counter_config[SCU_COUNTER(n)].count, &emc->MC[n]);
+}
+
+static inline void scu_set_event(struct eventmonitor __iomem *emc, unsigned int n, u32 event)
+{
+	event &= 0xff;
+	writeb(event, &emc->MCEB[n]);
+}
+
+/*
+ * SCU counters' IRQ handler (one IRQ per counter => 2 IRQs per CPU)
+ */
+static irqreturn_t scu_em_interrupt(int irq, void *arg)
+{
+	struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
+	unsigned int cnt;
+
+	cnt = irq - IRQ_PMU_SCU0;
+	oprofile_add_sample(get_irq_regs(), SCU_COUNTER(cnt));
+	scu_reset_counter(emc, cnt);
+
+	/* Clear overflow flag for this counter */
+	writel(1 << (cnt + 16), &emc->PMCR);
+
+	return IRQ_HANDLED;
+}
+
+/* Configure just the SCU counters that the user has requested */
+static void scu_setup(void)
+{
+	struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
+	unsigned int i;
+
+	scu_em_used = 0;
+
+	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
+		if (counter_config[SCU_COUNTER(i)].enabled &&
+		    counter_config[SCU_COUNTER(i)].event) {
+			scu_set_event(emc, i, 0); /* disable counter for now */
+			scu_em_used |= 1 << i;
+		}
+	}
+}
+
+static int scu_start(void)
+{
+	struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
+	unsigned int temp, i;
+	unsigned long event;
+	int ret = 0;
+
+	/*
+	 * request the SCU counter interrupts that we need
+	 */
+	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
+		if (scu_em_used & (1 << i)) {
+			ret = request_irq(IRQ_PMU_SCU0 + i, scu_em_interrupt, IRQF_DISABLED, "SCU PMU", NULL);
+			if (ret) {
+				printk(KERN_ERR "oprofile: unable to request IRQ%u for SCU Event Monitor\n",
+				       IRQ_PMU_SCU0 + i);
+				goto err_free_scu;
+			}
+		}
+	}
+
+	/*
+	 * clear overflow and enable interrupt for all used counters
+	 */
+	temp = readl(&emc->PMCR);
+	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
+		if (scu_em_used & (1 << i)) {
+			scu_reset_counter(emc, i);
+			event = counter_config[SCU_COUNTER(i)].event;
+			scu_set_event(emc, i, event);
+
+			/* clear overflow/interrupt */
+			temp |= 1 << (i + 16);
+			/* enable interrupt*/
+			temp |= 1 << (i + 8);
+		}
+	}
+
+	/* Enable all 8 counters */
+	temp |= PMCR_E;
+	writel(temp, &emc->PMCR);
+
+	return 0;
+
+ err_free_scu:
+	while (i--)
+		free_irq(IRQ_PMU_SCU0 + i, NULL);
+	return ret;
+}
+
+static void scu_stop(void)
+{
+	struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
+	unsigned int temp, i;
+
+	/* Disable counter interrupts */
+	/* Don't disable all 8 counters (with the E bit) as they may be in use */
+	temp = readl(&emc->PMCR);
+	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
+		if (scu_em_used & (1 << i))
+			temp &= ~(1 << (i + 8));
+	}
+	writel(temp, &emc->PMCR);
+
+	/* Free counter interrupts and reset counters */
+	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
+		if (scu_em_used & (1 << i)) {
+			scu_reset_counter(emc, i);
+			free_irq(IRQ_PMU_SCU0 + i, NULL);
+		}
+	}
+}
+
+struct em_function_data {
+	int (*fn)(void);
+	int ret;
+};
+
+static void em_func(void *data)
+{
+	struct em_function_data *d = data;
+	int ret = d->fn();
+	if (ret)
+		d->ret = ret;
+}
+
+static int em_call_function(int (*fn)(void))
+{
+	struct em_function_data data;
+
+	data.fn = fn;
+	data.ret = 0;
+
+	smp_call_function(em_func, &data, 1, 1);
+	em_func(&data);
+
+	return data.ret;
+}
+
+/*
+ * Glue to stick the individual ARM11 PMUs and the SCU
+ * into the oprofile framework.
+ */
+static int em_setup_ctrs(void)
+{
+	int ret;
+
+	/* Configure CPU counters by cross-calling to the other CPUs */
+	ret = em_call_function(arm11_setup_pmu);
+	if (ret == 0)
+		scu_setup();
+
+	return 0;
+}
+
+static int arm11_irqs[] = {
+	[0]	= IRQ_PMU_CPU0,
+	[1]	= IRQ_PMU_CPU1,
+	[2]	= IRQ_PMU_CPU2,
+	[3]	= IRQ_PMU_CPU3
+};
+
+static int em_start(void)
+{
+	int ret;
+
+	ret = arm11_request_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
+	if (ret == 0) {
+		em_call_function(arm11_start_pmu);
+
+		ret = scu_start();
+		if (ret)
+			arm11_release_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
+	}
+	return ret;
+}
+
+static void em_stop(void)
+{
+	em_call_function(arm11_stop_pmu);
+	arm11_release_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
+	scu_stop();
+}
+
+/*
+ * Why isn't there a function to route an IRQ to a specific CPU in
+ * genirq?
+ */
+static void em_route_irq(int irq, unsigned int cpu)
+{
+	irq_desc[irq].affinity = cpumask_of_cpu(cpu);
+	irq_desc[irq].chip->set_affinity(irq, cpumask_of_cpu(cpu));
+}
+
+static int em_setup(void)
+{
+	/*
+	 * Send SCU PMU interrupts to the "owner" CPU.
+	 */
+	em_route_irq(IRQ_PMU_SCU0, 0);
+	em_route_irq(IRQ_PMU_SCU1, 0);
+	em_route_irq(IRQ_PMU_SCU2, 1);
+	em_route_irq(IRQ_PMU_SCU3, 1);
+	em_route_irq(IRQ_PMU_SCU4, 2);
+	em_route_irq(IRQ_PMU_SCU5, 2);
+	em_route_irq(IRQ_PMU_SCU6, 3);
+	em_route_irq(IRQ_PMU_SCU7, 3);
+
+	/*
+	 * Send CP15 PMU interrupts to the owner CPU.
+	 */
+	em_route_irq(IRQ_PMU_CPU0, 0);
+	em_route_irq(IRQ_PMU_CPU1, 1);
+	em_route_irq(IRQ_PMU_CPU2, 2);
+	em_route_irq(IRQ_PMU_CPU3, 3);
+
+	return 0;
+}
+
+struct op_arm_model_spec op_mpcore_spec = {
+	.init		= em_setup,
+	.num_counters	= MPCORE_NUM_COUNTERS,
+	.setup_ctrs	= em_setup_ctrs,
+	.start		= em_start,
+	.stop		= em_stop,
+	.name		= "arm/mpcore",
+};
diff --git a/arch/arm/oprofile/op_model_mpcore.h b/arch/arm/oprofile/op_model_mpcore.h
new file mode 100644
index 0000000..73d8110
--- /dev/null
+++ b/arch/arm/oprofile/op_model_mpcore.h
@@ -0,0 +1,61 @@
+/**
+ * @file op_model_mpcore.c
+ * MPCORE Event Monitor Driver
+ * @remark Copyright 2004 ARM SMP Development Team
+ * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
+ * @remark Copyright 2000-2004 MontaVista Software Inc
+ * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
+ * @remark Copyright 2004 Intel Corporation
+ * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
+ * @remark Copyright 2004 Oprofile Authors
+ *
+ * @remark Read the file COPYING
+ *
+ * @author Zwane Mwaikambo
+ */
+#ifndef OP_MODEL_MPCORE_H
+#define OP_MODEL_MPCORE_H
+
+struct eventmonitor {
+	unsigned long PMCR;
+	unsigned char MCEB[8];
+	unsigned long MC[8];
+};
+
+/*
+ * List of userspace counter numbers: note that the structure is important.
+ * The code relies on CPUn's counters being CPU0's counters + 3n
+ * and on CPU0's counters starting at 0
+ */
+
+#define COUNTER_CPU0_PMN0 0
+#define COUNTER_CPU0_PMN1 1
+#define COUNTER_CPU0_CCNT 2
+
+#define COUNTER_CPU1_PMN0 3
+#define COUNTER_CPU1_PMN1 4
+#define COUNTER_CPU1_CCNT 5
+
+#define COUNTER_CPU2_PMN0 6
+#define COUNTER_CPU2_PMN1 7
+#define COUNTER_CPU2_CCNT 8
+
+#define COUNTER_CPU3_PMN0 9
+#define COUNTER_CPU3_PMN1 10
+#define COUNTER_CPU3_CCNT 11
+
+#define COUNTER_SCU_MN0 12
+#define COUNTER_SCU_MN1 13
+#define COUNTER_SCU_MN2 14
+#define COUNTER_SCU_MN3 15
+#define COUNTER_SCU_MN4 16
+#define COUNTER_SCU_MN5 17
+#define COUNTER_SCU_MN6 18
+#define COUNTER_SCU_MN7 19
+#define NUM_SCU_COUNTERS 8
+
+#define SCU_COUNTER(number)	((number) + COUNTER_SCU_MN0)
+
+#define MPCORE_NUM_COUNTERS	SCU_COUNTER(NUM_SCU_COUNTERS)
+
+#endif
diff --git a/arch/arm/oprofile/op_model_v6.c b/arch/arm/oprofile/op_model_v6.c
new file mode 100644
index 0000000..fe58138
--- /dev/null
+++ b/arch/arm/oprofile/op_model_v6.c
@@ -0,0 +1,67 @@
+/**
+ * @file op_model_v6.c
+ * ARM11 Performance Monitor Driver
+ *
+ * Based on op_model_xscale.c
+ *
+ * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
+ * @remark Copyright 2000-2004 MontaVista Software Inc
+ * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
+ * @remark Copyright 2004 Intel Corporation
+ * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
+ * @remark Copyright 2004 OProfile Authors
+ *
+ * @remark Read the file COPYING
+ *
+ * @author Tony Lindgren <tony@atomide.com>
+ */
+
+/* #define DEBUG */
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include "op_counter.h"
+#include "op_arm_model.h"
+#include "op_model_arm11_core.h"
+
+static int irqs[] = {
+#ifdef CONFIG_ARCH_OMAP2
+	3,
+#endif
+};
+
+static void armv6_pmu_stop(void)
+{
+	arm11_stop_pmu();
+	arm11_release_interrupts(irqs, ARRAY_SIZE(irqs));
+}
+
+static int armv6_pmu_start(void)
+{
+	int ret;
+
+	ret = arm11_request_interrupts(irqs, ARRAY_SIZE(irqs));
+	if (ret >= 0)
+		ret = arm11_start_pmu();
+
+	return ret;
+}
+
+static int armv6_detect_pmu(void)
+{
+	return 0;
+}
+
+struct op_arm_model_spec op_armv6_spec = {
+	.init		= armv6_detect_pmu,
+	.num_counters	= 3,
+	.setup_ctrs	= arm11_setup_pmu,
+	.start		= armv6_pmu_start,
+	.stop		= armv6_pmu_stop,
+	.name		= "arm/armv6",
+};
diff --git a/arch/arm/plat-iop/Makefile b/arch/arm/plat-iop/Makefile
index 23da00b..3250d73 100644
--- a/arch/arm/plat-iop/Makefile
+++ b/arch/arm/plat-iop/Makefile
@@ -2,7 +2,29 @@
 # Makefile for the linux kernel.
 #
 
-obj-y			:= gpio.o i2c.o pci.o setup.o time.o
-obj-m			:=
-obj-n			:=
-obj-			:=
+obj-y :=
+
+# IOP32X
+obj-$(CONFIG_ARCH_IOP32X) += gpio.o
+obj-$(CONFIG_ARCH_IOP32X) += i2c.o
+obj-$(CONFIG_ARCH_IOP32X) += pci.o
+obj-$(CONFIG_ARCH_IOP32X) += setup.o
+obj-$(CONFIG_ARCH_IOP32X) += time.o
+obj-$(CONFIG_ARCH_IOP32X) += io.o
+obj-$(CONFIG_ARCH_IOP32X) += cp6.o
+
+# IOP33X
+obj-$(CONFIG_ARCH_IOP33X) += gpio.o
+obj-$(CONFIG_ARCH_IOP33X) += i2c.o
+obj-$(CONFIG_ARCH_IOP33X) += pci.o
+obj-$(CONFIG_ARCH_IOP33X) += setup.o
+obj-$(CONFIG_ARCH_IOP33X) += time.o
+obj-$(CONFIG_ARCH_IOP33X) += io.o
+obj-$(CONFIG_ARCH_IOP33X) += cp6.o
+
+# IOP13XX
+obj-$(CONFIG_ARCH_IOP13XX) += cp6.o
+
+obj-m                  :=
+obj-n                  :=
+obj-                   :=
diff --git a/arch/arm/plat-iop/cp6.c b/arch/arm/plat-iop/cp6.c
new file mode 100644
index 0000000..9612a87
--- /dev/null
+++ b/arch/arm/plat-iop/cp6.c
@@ -0,0 +1,50 @@
+/*
+ * IOP Coprocessor-6 access handler
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+#include <linux/init.h>
+#include <asm/traps.h>
+
+static int cp6_trap(struct pt_regs *regs, unsigned int instr)
+{
+	u32 temp;
+
+        /* enable cp6 access */
+        asm volatile (
+		"mrc	p15, 0, %0, c15, c1, 0\n\t"
+		"orr	%0, %0, #(1 << 6)\n\t"
+		"mcr	p15, 0, %0, c15, c1, 0\n\t"
+		: "=r"(temp));
+
+	return 0;
+}
+
+/* permit kernel space cp6 access
+ * deny user space cp6 access
+ */
+static struct undef_hook cp6_hook = {
+	.instr_mask     = 0x0f000ff0,
+	.instr_val      = 0x0e000610,
+	.cpsr_mask      = MODE_MASK,
+	.cpsr_val       = SVC_MODE,
+	.fn             = cp6_trap,
+};
+
+void __init iop_init_cp6_handler(void)
+{
+	register_undef_hook(&cp6_hook);
+}
diff --git a/arch/arm/plat-iop/io.c b/arch/arm/plat-iop/io.c
new file mode 100644
index 0000000..f7eccec
--- /dev/null
+++ b/arch/arm/plat-iop/io.c
@@ -0,0 +1,58 @@
+/*
+ * iop3xx custom ioremap implementation
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size,
+	unsigned long flags)
+{
+	void __iomem * retval;
+
+	switch (cookie) {
+	case IOP3XX_PCI_LOWER_IO_PA ... IOP3XX_PCI_UPPER_IO_PA:
+		retval = (void *) IOP3XX_PCI_IO_PHYS_TO_VIRT(cookie);
+		break;
+	case IOP3XX_PERIPHERAL_PHYS_BASE ... IOP3XX_PERIPHERAL_UPPER_PA:
+		retval = (void *) IOP3XX_PMMR_PHYS_TO_VIRT(cookie);
+		break;
+	default:
+		retval = __ioremap(cookie, size, flags);
+	}
+
+	return retval;
+}
+EXPORT_SYMBOL(__iop3xx_ioremap);
+
+void __iop3xx_iounmap(void __iomem *addr)
+{
+	extern void __iounmap(volatile void __iomem *addr);
+
+	switch ((u32) addr) {
+	case IOP3XX_PCI_LOWER_IO_VA ... IOP3XX_PCI_UPPER_IO_VA:
+	case IOP3XX_PERIPHERAL_VIRT_BASE ... IOP3XX_PERIPHERAL_UPPER_VA:
+		goto skip;
+	}
+	__iounmap(addr);
+
+skip:
+	return;
+}
+EXPORT_SYMBOL(__iop3xx_iounmap);
diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c
index e647812..b5f6ec3 100644
--- a/arch/arm/plat-iop/pci.c
+++ b/arch/arm/plat-iop/pci.c
@@ -196,8 +196,8 @@
 	if (!res)
 		panic("PCI: unable to alloc resources");
 
-	res[0].start = IOP3XX_PCI_LOWER_IO_VA;
-	res[0].end   = IOP3XX_PCI_LOWER_IO_VA + IOP3XX_PCI_IO_WINDOW_SIZE - 1;
+	res[0].start = IOP3XX_PCI_LOWER_IO_PA;
+	res[0].end   = IOP3XX_PCI_LOWER_IO_PA + IOP3XX_PCI_IO_WINDOW_SIZE - 1;
 	res[0].name  = "IOP3XX PCI I/O Space";
 	res[0].flags = IORESOURCE_IO;
 	request_resource(&ioport_resource, &res[0]);
@@ -209,7 +209,7 @@
 	request_resource(&iomem_resource, &res[1]);
 
 	sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - IOP3XX_PCI_LOWER_MEM_BA;
-	sys->io_offset  = IOP3XX_PCI_LOWER_IO_VA - IOP3XX_PCI_LOWER_IO_BA;
+	sys->io_offset  = IOP3XX_PCI_LOWER_IO_PA - IOP3XX_PCI_LOWER_IO_BA;
 
 	sys->resource[0] = &res[0];
 	sys->resource[1] = &res[1];
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
new file mode 100644
index 0000000..e223431
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -0,0 +1,99 @@
+# arch/arm/plat-s3c24xx/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config PLAT_S3C24XX
+	bool
+	depends on ARCH_S3C2410
+	default y if ARCH_S3C2410
+	help
+	  Base platform code for any Samsung S3C device
+
+if PLAT_S3C24XX
+
+config CPU_S3C244X
+	bool
+	depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
+	help
+	  Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
+
+config PM_SIMTEC
+	bool
+	help
+	  Common power management code for systems that are
+	  compatible with the Simtec style of power management
+
+config S3C2410_BOOT_WATCHDOG
+	bool "S3C2410 Initialisation watchdog"
+	depends on ARCH_S3C2410 && S3C2410_WATCHDOG
+	help
+	  Say y to enable the watchdog during the kernel decompression
+	  stage. If the kernel fails to uncompress, then the watchdog
+	  will trigger a reset and the system should restart.
+
+config S3C2410_BOOT_ERROR_RESET
+	bool "S3C2410 Reboot on decompression error"
+	depends on ARCH_S3C2410
+	help
+	  Say y here to use the watchdog to reset the system if the
+	  kernel decompressor detects an error during decompression.
+
+config S3C2410_PM_DEBUG
+	bool "S3C2410 PM Suspend debug"
+	depends on ARCH_S3C2410 && PM
+	help
+	  Say Y here if you want verbose debugging from the PM Suspend and
+	  Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
+	  for more information.
+
+config S3C2410_PM_CHECK
+	bool "S3C2410 PM Suspend Memory CRC"
+	depends on ARCH_S3C2410 && PM && CRC32
+	help
+ 	  Enable the PM code's memory area checksum over sleep. This option
+	  will generate CRCs of all blocks of memory, and store them before
+	  going to sleep. The blocks are then checked on resume for any
+	  errors.
+
+config S3C2410_PM_CHECK_CHUNKSIZE
+	int "S3C2410 PM Suspend CRC Chunksize (KiB)"
+	depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK
+	default 64
+	help
+	  Set the chunksize in Kilobytes of the CRC for checking memory
+	  corruption over suspend and resume. A smaller value will mean that
+	  the CRC data block will take more memory, but wil identify any
+	  faults with better precision.
+
+config S3C2410_LOWLEVEL_UART_PORT
+	int "S3C2410 UART to use for low-level messages"
+	default 0
+	help
+	  Choice of which UART port to use for the low-level messages,
+	  such as the `Uncompressing...` at start time. The value of
+	  this configuration should be between zero and two. The port
+	  must have been initialised by the boot-loader before use.
+
+config S3C2410_DMA
+	bool "S3C2410 DMA support"
+	depends on ARCH_S3C2410
+	help
+	  S3C2410 DMA support. This is needed for drivers like sound which
+	  use the S3C2410's DMA system to move data to and from the
+	  peripheral blocks.
+
+config S3C2410_DMA_DEBUG
+	bool "S3C2410 DMA support debug"
+	depends on ARCH_S3C2410 && S3C2410_DMA
+	help
+	  Enable debugging output for the DMA code. This option sends info
+	  to the kernel log, at priority KERN_DEBUG.
+
+config MACH_SMDK
+	bool
+	help
+	  Common machine code for SMDK2410 and SMDK2440
+
+endif
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
new file mode 100644
index 0000000..8e5ccaa
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -0,0 +1,30 @@
+# arch/arm/plat-s3c24xx/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:=
+obj-				:=
+
+
+# Core files
+
+obj-y				+= cpu.o
+obj-y				+= irq.o
+obj-y				+= devs.o
+obj-y				+= gpio.o
+obj-y				+= time.o
+obj-y				+= clock.o
+
+# Architecture dependant builds
+
+obj-$(CONFIG_CPU_S3C244X)	+= s3c244x.o
+obj-$(CONFIG_CPU_S3C244X)	+= s3c244x-irq.o
+obj-$(CONFIG_PM_SIMTEC)		+= pm-simtec.o
+obj-$(CONFIG_PM)		+= pm.o
+obj-$(CONFIG_PM)		+= sleep.o
+obj-$(CONFIG_S3C2410_DMA)	+= dma.o
+obj-$(CONFIG_MACH_SMDK)		+= common-smdk.o
diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c
new file mode 100644
index 0000000..d3dc03a
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/clock.c
@@ -0,0 +1,449 @@
+/* linux/arch/arm/plat-s3c24xx/clock.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX Core clock control support
+ *
+ * Based on, and code from linux/arch/arm/mach-versatile/clock.c
+ **
+ **  Copyright (C) 2004 ARM Limited.
+ **  Written by Deep Blue Solutions Limited.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+/* clock information */
+
+static LIST_HEAD(clocks);
+
+DEFINE_MUTEX(clocks_mutex);
+
+/* enable and disable calls for use with the clk struct */
+
+static int clk_null_enable(struct clk *clk, int enable)
+{
+	return 0;
+}
+
+/* Clock API calls */
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	struct clk *p;
+	struct clk *clk = ERR_PTR(-ENOENT);
+	int idno;
+
+	if (dev == NULL || dev->bus != &platform_bus_type)
+		idno = -1;
+	else
+		idno = to_platform_device(dev)->id;
+
+	mutex_lock(&clocks_mutex);
+
+	list_for_each_entry(p, &clocks, list) {
+		if (p->id == idno &&
+		    strcmp(id, p->name) == 0 &&
+		    try_module_get(p->owner)) {
+			clk = p;
+			break;
+		}
+	}
+
+	/* check for the case where a device was supplied, but the
+	 * clock that was being searched for is not device specific */
+
+	if (IS_ERR(clk)) {
+		list_for_each_entry(p, &clocks, list) {
+			if (p->id == -1 && strcmp(id, p->name) == 0 &&
+			    try_module_get(p->owner)) {
+				clk = p;
+				break;
+			}
+		}
+	}
+
+	mutex_unlock(&clocks_mutex);
+	return clk;
+}
+
+void clk_put(struct clk *clk)
+{
+	module_put(clk->owner);
+}
+
+int clk_enable(struct clk *clk)
+{
+	if (IS_ERR(clk) || clk == NULL)
+		return -EINVAL;
+
+	clk_enable(clk->parent);
+
+	mutex_lock(&clocks_mutex);
+
+	if ((clk->usage++) == 0)
+		(clk->enable)(clk, 1);
+
+	mutex_unlock(&clocks_mutex);
+	return 0;
+}
+
+void clk_disable(struct clk *clk)
+{
+	if (IS_ERR(clk) || clk == NULL)
+		return;
+
+	mutex_lock(&clocks_mutex);
+
+	if ((--clk->usage) == 0)
+		(clk->enable)(clk, 0);
+
+	mutex_unlock(&clocks_mutex);
+	clk_disable(clk->parent);
+}
+
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (IS_ERR(clk))
+		return 0;
+
+	if (clk->rate != 0)
+		return clk->rate;
+
+	if (clk->get_rate != NULL)
+		return (clk->get_rate)(clk);
+
+	if (clk->parent != NULL)
+		return clk_get_rate(clk->parent);
+
+	return clk->rate;
+}
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (!IS_ERR(clk) && clk->round_rate)
+		return (clk->round_rate)(clk, rate);
+
+	return rate;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int ret;
+
+	if (IS_ERR(clk))
+		return -EINVAL;
+
+	mutex_lock(&clocks_mutex);
+	ret = (clk->set_rate)(clk, rate);
+	mutex_unlock(&clocks_mutex);
+
+	return ret;
+}
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+	return clk->parent;
+}
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	int ret = 0;
+
+	if (IS_ERR(clk))
+		return -EINVAL;
+
+	mutex_lock(&clocks_mutex);
+
+	if (clk->set_parent)
+		ret = (clk->set_parent)(clk, parent);
+
+	mutex_unlock(&clocks_mutex);
+
+	return ret;
+}
+
+EXPORT_SYMBOL(clk_get);
+EXPORT_SYMBOL(clk_put);
+EXPORT_SYMBOL(clk_enable);
+EXPORT_SYMBOL(clk_disable);
+EXPORT_SYMBOL(clk_get_rate);
+EXPORT_SYMBOL(clk_round_rate);
+EXPORT_SYMBOL(clk_set_rate);
+EXPORT_SYMBOL(clk_get_parent);
+EXPORT_SYMBOL(clk_set_parent);
+
+/* base clocks */
+
+struct clk clk_xtal = {
+	.name		= "xtal",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+};
+
+struct clk clk_mpll = {
+	.name		= "mpll",
+	.id		= -1,
+};
+
+struct clk clk_upll = {
+	.name		= "upll",
+	.id		= -1,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+};
+
+struct clk clk_f = {
+	.name		= "fclk",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= &clk_mpll,
+	.ctrlbit	= 0,
+};
+
+struct clk clk_h = {
+	.name		= "hclk",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+};
+
+struct clk clk_p = {
+	.name		= "pclk",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+};
+
+struct clk clk_usb_bus = {
+	.name		= "usb-bus",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= &clk_upll,
+};
+
+/* clocks that could be registered by external code */
+
+static int s3c24xx_dclk_enable(struct clk *clk, int enable)
+{
+	unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
+
+	if (enable)
+		dclkcon |= clk->ctrlbit;
+	else
+		dclkcon &= ~clk->ctrlbit;
+
+	__raw_writel(dclkcon, S3C24XX_DCLKCON);
+
+	return 0;
+}
+
+static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
+{
+	unsigned long dclkcon;
+	unsigned int uclk;
+
+	if (parent == &clk_upll)
+		uclk = 1;
+	else if (parent == &clk_p)
+		uclk = 0;
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	dclkcon = __raw_readl(S3C24XX_DCLKCON);
+
+	if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
+		if (uclk)
+			dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
+		else
+			dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
+	} else {
+		if (uclk)
+			dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
+		else
+			dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
+	}
+
+	__raw_writel(dclkcon, S3C24XX_DCLKCON);
+
+	return 0;
+}
+
+
+static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
+{
+	unsigned long mask;
+	unsigned long source;
+
+	/* calculate the MISCCR setting for the clock */
+
+	if (parent == &clk_xtal)
+		source = S3C2410_MISCCR_CLK0_MPLL;
+	else if (parent == &clk_upll)
+		source = S3C2410_MISCCR_CLK0_UPLL;
+	else if (parent == &clk_f)
+		source = S3C2410_MISCCR_CLK0_FCLK;
+	else if (parent == &clk_h)
+		source = S3C2410_MISCCR_CLK0_HCLK;
+	else if (parent == &clk_p)
+		source = S3C2410_MISCCR_CLK0_PCLK;
+	else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
+		source = S3C2410_MISCCR_CLK0_DCLK0;
+	else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
+		source = S3C2410_MISCCR_CLK0_DCLK0;
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	if (clk == &s3c24xx_dclk0)
+		mask = S3C2410_MISCCR_CLK0_MASK;
+	else {
+		source <<= 4;
+		mask = S3C2410_MISCCR_CLK1_MASK;
+	}
+
+	s3c2410_modify_misccr(mask, source);
+	return 0;
+}
+
+/* external clock definitions */
+
+struct clk s3c24xx_dclk0 = {
+	.name		= "dclk0",
+	.id		= -1,
+	.ctrlbit	= S3C2410_DCLKCON_DCLK0EN,
+	.enable	        = s3c24xx_dclk_enable,
+	.set_parent	= s3c24xx_dclk_setparent,
+};
+
+struct clk s3c24xx_dclk1 = {
+	.name		= "dclk1",
+	.id		= -1,
+	.ctrlbit	= S3C2410_DCLKCON_DCLK0EN,
+	.enable		= s3c24xx_dclk_enable,
+	.set_parent	= s3c24xx_dclk_setparent,
+};
+
+struct clk s3c24xx_clkout0 = {
+	.name		= "clkout0",
+	.id		= -1,
+	.set_parent	= s3c24xx_clkout_setparent,
+};
+
+struct clk s3c24xx_clkout1 = {
+	.name		= "clkout1",
+	.id		= -1,
+	.set_parent	= s3c24xx_clkout_setparent,
+};
+
+struct clk s3c24xx_uclk = {
+	.name		= "uclk",
+	.id		= -1,
+};
+
+/* initialise the clock system */
+
+int s3c24xx_register_clock(struct clk *clk)
+{
+	clk->owner = THIS_MODULE;
+
+	if (clk->enable == NULL)
+		clk->enable = clk_null_enable;
+
+	/* add to the list of available clocks */
+
+	mutex_lock(&clocks_mutex);
+	list_add(&clk->list, &clocks);
+	mutex_unlock(&clocks_mutex);
+
+	return 0;
+}
+
+/* initalise all the clocks */
+
+int __init s3c24xx_setup_clocks(unsigned long xtal,
+				unsigned long fclk,
+				unsigned long hclk,
+				unsigned long pclk)
+{
+	printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n");
+
+	/* initialise the main system clocks */
+
+	clk_xtal.rate = xtal;
+	clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal);
+
+	clk_mpll.rate = fclk;
+	clk_h.rate = hclk;
+	clk_p.rate = pclk;
+	clk_f.rate = fclk;
+
+	/* assume uart clocks are correctly setup */
+
+	/* register our clocks */
+
+	if (s3c24xx_register_clock(&clk_xtal) < 0)
+		printk(KERN_ERR "failed to register master xtal\n");
+
+	if (s3c24xx_register_clock(&clk_mpll) < 0)
+		printk(KERN_ERR "failed to register mpll clock\n");
+
+	if (s3c24xx_register_clock(&clk_upll) < 0)
+		printk(KERN_ERR "failed to register upll clock\n");
+
+	if (s3c24xx_register_clock(&clk_f) < 0)
+		printk(KERN_ERR "failed to register cpu fclk\n");
+
+	if (s3c24xx_register_clock(&clk_h) < 0)
+		printk(KERN_ERR "failed to register cpu hclk\n");
+
+	if (s3c24xx_register_clock(&clk_p) < 0)
+		printk(KERN_ERR "failed to register cpu pclk\n");
+
+	return 0;
+}
diff --git a/arch/arm/mach-s3c2410/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c
similarity index 96%
rename from arch/arm/mach-s3c2410/common-smdk.c
rename to arch/arm/plat-s3c24xx/common-smdk.c
index a40eaa6..908efa7 100644
--- a/arch/arm/mach-s3c2410/common-smdk.c
+++ b/arch/arm/plat-s3c24xx/common-smdk.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/common-smdk.c
+/* linux/arch/arm/plat-s3c24xx/common-smdk.c
  *
  * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -38,9 +38,9 @@
 
 #include <asm/arch/nand.h>
 
-#include "common-smdk.h"
-#include "devs.h"
-#include "pm.h"
+#include <asm/plat-s3c24xx/common-smdk.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/pm.h>
 
 /* LED devices */
 
diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
similarity index 92%
rename from arch/arm/mach-s3c2410/cpu.c
rename to arch/arm/plat-s3c24xx/cpu.c
index ae1f5bb..6a2d107 100644
--- a/arch/arm/mach-s3c2410/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/cpu.c
+/* linux/arch/arm/plat-s3c24xx/cpu.c
  *
  * Copyright (c) 2004-2005 Simtec Electronics
  *	http://www.simtec.co.uk/products/SWLINUX/
@@ -40,15 +40,16 @@
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-serial.h>
 
-#include "cpu.h"
-#include "devs.h"
-#include "clock.h"
-#include "s3c2400.h"
-#include "s3c2410.h"
-#include "s3c2412.h"
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/s3c2400.h>
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/s3c2412.h>
 #include "s3c244x.h"
-#include "s3c2440.h"
-#include "s3c2442.h"
+#include <asm/plat-s3c24xx/s3c2440.h>
+#include <asm/plat-s3c24xx/s3c2442.h>
+#include <asm/plat-s3c24xx/s3c2443.h>
 
 struct cpu_table {
 	unsigned long	idcode;
@@ -67,6 +68,7 @@
 static const char name_s3c2412[]  = "S3C2412";
 static const char name_s3c2440[]  = "S3C2440";
 static const char name_s3c2442[]  = "S3C2442";
+static const char name_s3c2443[]  = "S3C2443";
 static const char name_s3c2410a[] = "S3C2410A";
 static const char name_s3c2440a[] = "S3C2440A";
 
@@ -135,6 +137,15 @@
 		.name		= name_s3c2412,
 	},
 	{
+		.idcode		= 0x32443001,
+		.idmask		= 0xffffffff,
+		.map_io		= s3c2443_map_io,
+		.init_clocks	= s3c2443_init_clocks,
+		.init_uarts	= s3c2443_init_uarts,
+		.init		= s3c2443_init,
+		.name		= name_s3c2443,
+	},
+	{
 		.idcode		= 0x0,   /* S3C2400 doesn't have an idcode */
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2400_map_io,
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/plat-s3c24xx/devs.c
similarity index 95%
rename from arch/arm/mach-s3c2410/devs.c
rename to arch/arm/plat-s3c24xx/devs.c
index faccde2..0fe53b3 100644
--- a/arch/arm/mach-s3c2410/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/devs.c
+/* linux/arch/arm/plat-s3c24xx/devs.c
  *
  * Copyright (c) 2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -29,9 +29,10 @@
 #include <asm/irq.h>
 
 #include <asm/arch/regs-serial.h>
+#include <asm/arch/udc.h>
 
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 /* Serial port registrations */
 
@@ -230,6 +231,20 @@
 
 EXPORT_SYMBOL(s3c_device_usbgadget);
 
+void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
+{
+	struct s3c2410_udc_mach_info *npd;
+
+	npd = kmalloc(sizeof(*npd), GFP_KERNEL);
+	if (npd) {
+		memcpy(npd, pd, sizeof(*npd));
+		s3c_device_usbgadget.dev.platform_data = npd;
+	} else {
+		printk(KERN_ERR "no memory for udc platform data\n");
+	}
+}
+
+
 /* Watchdog */
 
 static struct resource s3c_wdt_resource[] = {
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
new file mode 100644
index 0000000..4540a80
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -0,0 +1,1499 @@
+/* linux/arch/arm/plat-s3c24xx/dma.c
+ *
+ * Copyright (c) 2003-2005,2006 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 DMA core
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+
+#ifdef CONFIG_S3C2410_DMA_DEBUG
+#define DEBUG
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+#include <asm/mach/dma.h>
+#include <asm/arch/map.h>
+
+#include <asm/plat-s3c24xx/dma.h>
+
+/* io map for dma */
+static void __iomem *dma_base;
+static struct kmem_cache *dma_kmem;
+
+static int dma_channels;
+
+struct s3c24xx_dma_selection dma_sel;
+
+/* dma channel state information */
+struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
+
+/* debugging functions */
+
+#define BUF_MAGIC (0xcafebabe)
+
+#define dmawarn(fmt...) printk(KERN_DEBUG fmt)
+
+#define dma_regaddr(chan, reg) ((chan)->regs + (reg))
+
+#if 1
+#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg))
+#else
+static inline void
+dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
+{
+	pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
+	writel(val, dma_regaddr(chan, reg));
+}
+#endif
+
+#define dma_rdreg(chan, reg) readl((chan)->regs + (reg))
+
+/* captured register state for debug */
+
+struct s3c2410_dma_regstate {
+	unsigned long         dcsrc;
+	unsigned long         disrc;
+	unsigned long         dstat;
+	unsigned long         dcon;
+	unsigned long         dmsktrig;
+};
+
+#ifdef CONFIG_S3C2410_DMA_DEBUG
+
+/* dmadbg_showregs
+ *
+ * simple debug routine to print the current state of the dma registers
+*/
+
+static void
+dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs)
+{
+	regs->dcsrc    = dma_rdreg(chan, S3C2410_DMA_DCSRC);
+	regs->disrc    = dma_rdreg(chan, S3C2410_DMA_DISRC);
+	regs->dstat    = dma_rdreg(chan, S3C2410_DMA_DSTAT);
+	regs->dcon     = dma_rdreg(chan, S3C2410_DMA_DCON);
+	regs->dmsktrig = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+}
+
+static void
+dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *chan,
+		 struct s3c2410_dma_regstate *regs)
+{
+	printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",
+	       chan->number, fname, line,
+	       regs->dcsrc, regs->disrc, regs->dstat, regs->dmsktrig,
+	       regs->dcon);
+}
+
+static void
+dmadbg_showchan(const char *fname, int line, struct s3c2410_dma_chan *chan)
+{
+	struct s3c2410_dma_regstate state;
+
+	dmadbg_capture(chan, &state);
+
+	printk(KERN_DEBUG "dma%d: %s:%d: ls=%d, cur=%p, %p %p\n",
+	       chan->number, fname, line, chan->load_state,
+	       chan->curr, chan->next, chan->end);
+
+	dmadbg_dumpregs(fname, line, chan, &state);
+}
+
+static void
+dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
+{
+	struct s3c2410_dma_regstate state;
+
+	dmadbg_capture(chan, &state);
+	dmadbg_dumpregs(fname, line, chan, &state);
+}
+
+#define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan))
+#define dbg_showchan(chan) dmadbg_showchan(__FUNCTION__, __LINE__, (chan))
+#else
+#define dbg_showregs(chan) do { } while(0)
+#define dbg_showchan(chan) do { } while(0)
+#endif /* CONFIG_S3C2410_DMA_DEBUG */
+
+static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX];
+
+/* lookup_dma_channel
+ *
+ * change the dma channel number given into a real dma channel id
+*/
+
+static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel)
+{
+	if (channel & DMACH_LOW_LEVEL)
+		return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
+	else
+		return dma_chan_map[channel];
+}
+
+/* s3c2410_dma_stats_timeout
+ *
+ * Update DMA stats from timeout info
+*/
+
+static void
+s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val)
+{
+	if (stats == NULL)
+		return;
+
+	if (val > stats->timeout_longest)
+		stats->timeout_longest = val;
+	if (val < stats->timeout_shortest)
+		stats->timeout_shortest = val;
+
+	stats->timeout_avg += val;
+}
+
+/* s3c2410_dma_waitforload
+ *
+ * wait for the DMA engine to load a buffer, and update the state accordingly
+*/
+
+static int
+s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)
+{
+	int timeout = chan->load_timeout;
+	int took;
+
+	if (chan->load_state != S3C2410_DMALOAD_1LOADED) {
+		printk(KERN_ERR "dma%d: s3c2410_dma_waitforload() called in loadstate %d from line %d\n", chan->number, chan->load_state, line);
+		return 0;
+	}
+
+	if (chan->stats != NULL)
+		chan->stats->loads++;
+
+	while (--timeout > 0) {
+		if ((dma_rdreg(chan, S3C2410_DMA_DSTAT) << (32-20)) != 0) {
+			took = chan->load_timeout - timeout;
+
+			s3c2410_dma_stats_timeout(chan->stats, took);
+
+			switch (chan->load_state) {
+			case S3C2410_DMALOAD_1LOADED:
+				chan->load_state = S3C2410_DMALOAD_1RUNNING;
+				break;
+
+			default:
+				printk(KERN_ERR "dma%d: unknown load_state in s3c2410_dma_waitforload() %d\n", chan->number, chan->load_state);
+			}
+
+			return 1;
+		}
+	}
+
+	if (chan->stats != NULL) {
+		chan->stats->timeout_failed++;
+	}
+
+	return 0;
+}
+
+
+
+/* s3c2410_dma_loadbuffer
+ *
+ * load a buffer, and update the channel state
+*/
+
+static inline int
+s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
+		       struct s3c2410_dma_buf *buf)
+{
+	unsigned long reload;
+
+	pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
+		 buf, (unsigned long)buf->data, buf->size);
+
+	if (buf == NULL) {
+		dmawarn("buffer is NULL\n");
+		return -EINVAL;
+	}
+
+	/* check the state of the channel before we do anything */
+
+	if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+		dmawarn("load_state is S3C2410_DMALOAD_1LOADED\n");
+	}
+
+	if (chan->load_state == S3C2410_DMALOAD_1LOADED_1RUNNING) {
+		dmawarn("state is S3C2410_DMALOAD_1LOADED_1RUNNING\n");
+	}
+
+	/* it would seem sensible if we are the last buffer to not bother
+	 * with the auto-reload bit, so that the DMA engine will not try
+	 * and load another transfer after this one has finished...
+	 */
+	if (chan->load_state == S3C2410_DMALOAD_NONE) {
+		pr_debug("load_state is none, checking for noreload (next=%p)\n",
+			 buf->next);
+		reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
+	} else {
+		//pr_debug("load_state is %d => autoreload\n", chan->load_state);
+		reload = S3C2410_DCON_AUTORELOAD;
+	}
+
+	if ((buf->data & 0xf0000000) != 0x30000000) {
+		dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
+	}
+
+	writel(buf->data, chan->addr_reg);
+
+	dma_wrreg(chan, S3C2410_DMA_DCON,
+		  chan->dcon | reload | (buf->size/chan->xfer_unit));
+
+	chan->next = buf->next;
+
+	/* update the state of the channel */
+
+	switch (chan->load_state) {
+	case S3C2410_DMALOAD_NONE:
+		chan->load_state = S3C2410_DMALOAD_1LOADED;
+		break;
+
+	case S3C2410_DMALOAD_1RUNNING:
+		chan->load_state = S3C2410_DMALOAD_1LOADED_1RUNNING;
+		break;
+
+	default:
+		dmawarn("dmaload: unknown state %d in loadbuffer\n",
+			chan->load_state);
+		break;
+	}
+
+	return 0;
+}
+
+/* s3c2410_dma_call_op
+ *
+ * small routine to call the op routine with the given op if it has been
+ * registered
+*/
+
+static void
+s3c2410_dma_call_op(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op op)
+{
+	if (chan->op_fn != NULL) {
+		(chan->op_fn)(chan, op);
+	}
+}
+
+/* s3c2410_dma_buffdone
+ *
+ * small wrapper to check if callback routine needs to be called, and
+ * if so, call it
+*/
+
+static inline void
+s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
+		     enum s3c2410_dma_buffresult result)
+{
+#if 0
+	pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
+		 chan->callback_fn, buf, buf->id, buf->size, result);
+#endif
+
+	if (chan->callback_fn != NULL) {
+		(chan->callback_fn)(chan, buf->id, buf->size, result);
+	}
+}
+
+/* s3c2410_dma_start
+ *
+ * start a dma channel going
+*/
+
+static int s3c2410_dma_start(struct s3c2410_dma_chan *chan)
+{
+	unsigned long tmp;
+	unsigned long flags;
+
+	pr_debug("s3c2410_start_dma: channel=%d\n", chan->number);
+
+	local_irq_save(flags);
+
+	if (chan->state == S3C2410_DMA_RUNNING) {
+		pr_debug("s3c2410_start_dma: already running (%d)\n", chan->state);
+		local_irq_restore(flags);
+		return 0;
+	}
+
+	chan->state = S3C2410_DMA_RUNNING;
+
+	/* check wether there is anything to load, and if not, see
+	 * if we can find anything to load
+	 */
+
+	if (chan->load_state == S3C2410_DMALOAD_NONE) {
+		if (chan->next == NULL) {
+			printk(KERN_ERR "dma%d: channel has nothing loaded\n",
+			       chan->number);
+			chan->state = S3C2410_DMA_IDLE;
+			local_irq_restore(flags);
+			return -EINVAL;
+		}
+
+		s3c2410_dma_loadbuffer(chan, chan->next);
+	}
+
+	dbg_showchan(chan);
+
+	/* enable the channel */
+
+	if (!chan->irq_enabled) {
+		enable_irq(chan->irq);
+		chan->irq_enabled = 1;
+	}
+
+	/* start the channel going */
+
+	tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+	tmp &= ~S3C2410_DMASKTRIG_STOP;
+	tmp |= S3C2410_DMASKTRIG_ON;
+	dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
+
+	pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
+
+#if 0
+	/* the dma buffer loads should take care of clearing the AUTO
+	 * reloading feature */
+	tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
+	tmp &= ~S3C2410_DCON_NORELOAD;
+	dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
+#endif
+
+	s3c2410_dma_call_op(chan, S3C2410_DMAOP_START);
+
+	dbg_showchan(chan);
+
+	/* if we've only loaded one buffer onto the channel, then chec
+	 * to see if we have another, and if so, try and load it so when
+	 * the first buffer is finished, the new one will be loaded onto
+	 * the channel */
+
+	if (chan->next != NULL) {
+		if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+
+			if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+				pr_debug("%s: buff not yet loaded, no more todo\n",
+					 __FUNCTION__);
+			} else {
+				chan->load_state = S3C2410_DMALOAD_1RUNNING;
+				s3c2410_dma_loadbuffer(chan, chan->next);
+			}
+
+		} else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
+			s3c2410_dma_loadbuffer(chan, chan->next);
+		}
+	}
+
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+/* s3c2410_dma_canload
+ *
+ * work out if we can queue another buffer into the DMA engine
+*/
+
+static int
+s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
+{
+	if (chan->load_state == S3C2410_DMALOAD_NONE ||
+	    chan->load_state == S3C2410_DMALOAD_1RUNNING)
+		return 1;
+
+	return 0;
+}
+
+/* s3c2410_dma_enqueue
+ *
+ * queue an given buffer for dma transfer.
+ *
+ * id         the device driver's id information for this buffer
+ * data       the physical address of the buffer data
+ * size       the size of the buffer in bytes
+ *
+ * If the channel is not running, then the flag S3C2410_DMAF_AUTOSTART
+ * is checked, and if set, the channel is started. If this flag isn't set,
+ * then an error will be returned.
+ *
+ * It is possible to queue more than one DMA buffer onto a channel at
+ * once, and the code will deal with the re-loading of the next buffer
+ * when necessary.
+*/
+
+int s3c2410_dma_enqueue(unsigned int channel, void *id,
+			dma_addr_t data, int size)
+{
+	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+	struct s3c2410_dma_buf *buf;
+	unsigned long flags;
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	pr_debug("%s: id=%p, data=%08x, size=%d\n",
+		 __FUNCTION__, id, (unsigned int)data, size);
+
+	buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
+	if (buf == NULL) {
+		pr_debug("%s: out of memory (%ld alloc)\n",
+			 __FUNCTION__, (long)sizeof(*buf));
+		return -ENOMEM;
+	}
+
+	//pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);
+	//dbg_showchan(chan);
+
+	buf->next  = NULL;
+	buf->data  = buf->ptr = data;
+	buf->size  = size;
+	buf->id    = id;
+	buf->magic = BUF_MAGIC;
+
+	local_irq_save(flags);
+
+	if (chan->curr == NULL) {
+		/* we've got nothing loaded... */
+		pr_debug("%s: buffer %p queued onto empty channel\n",
+			 __FUNCTION__, buf);
+
+		chan->curr = buf;
+		chan->end  = buf;
+		chan->next = NULL;
+	} else {
+		pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
+			 chan->number, __FUNCTION__, buf);
+
+		if (chan->end == NULL)
+			pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
+				 chan->number, __FUNCTION__, chan);
+
+		chan->end->next = buf;
+		chan->end = buf;
+	}
+
+	/* if necessary, update the next buffer field */
+	if (chan->next == NULL)
+		chan->next = buf;
+
+	/* check to see if we can load a buffer */
+	if (chan->state == S3C2410_DMA_RUNNING) {
+		if (chan->load_state == S3C2410_DMALOAD_1LOADED && 1) {
+			if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+				printk(KERN_ERR "dma%d: loadbuffer:"
+				       "timeout loading buffer\n",
+				       chan->number);
+				dbg_showchan(chan);
+				local_irq_restore(flags);
+				return -EINVAL;
+			}
+		}
+
+		while (s3c2410_dma_canload(chan) && chan->next != NULL) {
+			s3c2410_dma_loadbuffer(chan, chan->next);
+		}
+	} else if (chan->state == S3C2410_DMA_IDLE) {
+		if (chan->flags & S3C2410_DMAF_AUTOSTART) {
+			s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_START);
+		}
+	}
+
+	local_irq_restore(flags);
+	return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_enqueue);
+
+static inline void
+s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
+{
+	int magicok = (buf->magic == BUF_MAGIC);
+
+	buf->magic = -1;
+
+	if (magicok) {
+		kmem_cache_free(dma_kmem, buf);
+	} else {
+		printk("s3c2410_dma_freebuf: buff %p with bad magic\n", buf);
+	}
+}
+
+/* s3c2410_dma_lastxfer
+ *
+ * called when the system is out of buffers, to ensure that the channel
+ * is prepared for shutdown.
+*/
+
+static inline void
+s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
+{
+#if 0
+	pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
+		 chan->number, chan->load_state);
+#endif
+
+	switch (chan->load_state) {
+	case S3C2410_DMALOAD_NONE:
+		break;
+
+	case S3C2410_DMALOAD_1LOADED:
+		if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+				/* flag error? */
+			printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
+			       chan->number, __FUNCTION__);
+			return;
+		}
+		break;
+
+	case S3C2410_DMALOAD_1LOADED_1RUNNING:
+		/* I belive in this case we do not have anything to do
+		 * until the next buffer comes along, and we turn off the
+		 * reload */
+		return;
+
+	default:
+		pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
+			 chan->number, chan->load_state);
+		return;
+
+	}
+
+	/* hopefully this'll shut the damned thing up after the transfer... */
+	dma_wrreg(chan, S3C2410_DMA_DCON, chan->dcon | S3C2410_DCON_NORELOAD);
+}
+
+
+#define dmadbg2(x...)
+
+static irqreturn_t
+s3c2410_dma_irq(int irq, void *devpw)
+{
+	struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw;
+	struct s3c2410_dma_buf  *buf;
+
+	buf = chan->curr;
+
+	dbg_showchan(chan);
+
+	/* modify the channel state */
+
+	switch (chan->load_state) {
+	case S3C2410_DMALOAD_1RUNNING:
+		/* TODO - if we are running only one buffer, we probably
+		 * want to reload here, and then worry about the buffer
+		 * callback */
+
+		chan->load_state = S3C2410_DMALOAD_NONE;
+		break;
+
+	case S3C2410_DMALOAD_1LOADED:
+		/* iirc, we should go back to NONE loaded here, we
+		 * had a buffer, and it was never verified as being
+		 * loaded.
+		 */
+
+		chan->load_state = S3C2410_DMALOAD_NONE;
+		break;
+
+	case S3C2410_DMALOAD_1LOADED_1RUNNING:
+		/* we'll worry about checking to see if another buffer is
+		 * ready after we've called back the owner. This should
+		 * ensure we do not wait around too long for the DMA
+		 * engine to start the next transfer
+		 */
+
+		chan->load_state = S3C2410_DMALOAD_1LOADED;
+		break;
+
+	case S3C2410_DMALOAD_NONE:
+		printk(KERN_ERR "dma%d: IRQ with no loaded buffer?\n",
+		       chan->number);
+		break;
+
+	default:
+		printk(KERN_ERR "dma%d: IRQ in invalid load_state %d\n",
+		       chan->number, chan->load_state);
+		break;
+	}
+
+	if (buf != NULL) {
+		/* update the chain to make sure that if we load any more
+		 * buffers when we call the callback function, things should
+		 * work properly */
+
+		chan->curr = buf->next;
+		buf->next  = NULL;
+
+		if (buf->magic != BUF_MAGIC) {
+			printk(KERN_ERR "dma%d: %s: buf %p incorrect magic\n",
+			       chan->number, __FUNCTION__, buf);
+			return IRQ_HANDLED;
+		}
+
+		s3c2410_dma_buffdone(chan, buf, S3C2410_RES_OK);
+
+		/* free resouces */
+		s3c2410_dma_freebuf(buf);
+	} else {
+	}
+
+	/* only reload if the channel is still running... our buffer done
+	 * routine may have altered the state by requesting the dma channel
+	 * to stop or shutdown... */
+
+	/* todo: check that when the channel is shut-down from inside this
+	 * function, we cope with unsetting reload, etc */
+
+	if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
+		unsigned long flags;
+
+		switch (chan->load_state) {
+		case S3C2410_DMALOAD_1RUNNING:
+			/* don't need to do anything for this state */
+			break;
+
+		case S3C2410_DMALOAD_NONE:
+			/* can load buffer immediately */
+			break;
+
+		case S3C2410_DMALOAD_1LOADED:
+			if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+				/* flag error? */
+				printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
+				       chan->number, __FUNCTION__);
+				return IRQ_HANDLED;
+			}
+
+			break;
+
+		case S3C2410_DMALOAD_1LOADED_1RUNNING:
+			goto no_load;
+
+		default:
+			printk(KERN_ERR "dma%d: unknown load_state in irq, %d\n",
+			       chan->number, chan->load_state);
+			return IRQ_HANDLED;
+		}
+
+		local_irq_save(flags);
+		s3c2410_dma_loadbuffer(chan, chan->next);
+		local_irq_restore(flags);
+	} else {
+		s3c2410_dma_lastxfer(chan);
+
+		/* see if we can stop this channel.. */
+		if (chan->load_state == S3C2410_DMALOAD_NONE) {
+			pr_debug("dma%d: end of transfer, stopping channel (%ld)\n",
+				 chan->number, jiffies);
+			s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
+					 S3C2410_DMAOP_STOP);
+		}
+	}
+
+ no_load:
+	return IRQ_HANDLED;
+}
+
+static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel);
+
+/* s3c2410_request_dma
+ *
+ * get control of an dma channel
+*/
+
+int s3c2410_dma_request(unsigned int channel,
+			struct s3c2410_dma_client *client,
+			void *dev)
+{
+	struct s3c2410_dma_chan *chan;
+	unsigned long flags;
+	int err;
+
+	pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
+		 channel, client->name, dev);
+
+	local_irq_save(flags);
+
+	chan = s3c2410_dma_map_channel(channel);
+	if (chan == NULL) {
+		local_irq_restore(flags);
+		return -EBUSY;
+	}
+
+	dbg_showchan(chan);
+
+	chan->client = client;
+	chan->in_use = 1;
+
+	if (!chan->irq_claimed) {
+		pr_debug("dma%d: %s : requesting irq %d\n",
+			 channel, __FUNCTION__, chan->irq);
+
+		chan->irq_claimed = 1;
+		local_irq_restore(flags);
+
+		err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
+				  client->name, (void *)chan);
+
+		local_irq_save(flags);
+
+		if (err) {
+			chan->in_use = 0;
+			chan->irq_claimed = 0;
+			local_irq_restore(flags);
+
+			printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",
+			       client->name, chan->irq, chan->number);
+			return err;
+		}
+
+		chan->irq_enabled = 1;
+	}
+
+	local_irq_restore(flags);
+
+	/* need to setup */
+
+	pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_request);
+
+/* s3c2410_dma_free
+ *
+ * release the given channel back to the system, will stop and flush
+ * any outstanding transfers, and ensure the channel is ready for the
+ * next claimant.
+ *
+ * Note, although a warning is currently printed if the freeing client
+ * info is not the same as the registrant's client info, the free is still
+ * allowed to go through.
+*/
+
+int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client)
+{
+	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+	unsigned long flags;
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	local_irq_save(flags);
+
+	if (chan->client != client) {
+		printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
+		       channel, chan->client, client);
+	}
+
+	/* sort out stopping and freeing the channel */
+
+	if (chan->state != S3C2410_DMA_IDLE) {
+		pr_debug("%s: need to stop dma channel %p\n",
+		       __FUNCTION__, chan);
+
+		/* possibly flush the channel */
+		s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STOP);
+	}
+
+	chan->client = NULL;
+	chan->in_use = 0;
+
+	if (chan->irq_claimed)
+		free_irq(chan->irq, (void *)chan);
+
+	chan->irq_claimed = 0;
+
+	if (!(channel & DMACH_LOW_LEVEL))
+		dma_chan_map[channel] = NULL;
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_free);
+
+static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
+{
+	unsigned long flags;
+	unsigned long tmp;
+
+	pr_debug("%s:\n", __FUNCTION__);
+
+	dbg_showchan(chan);
+
+	local_irq_save(flags);
+
+	s3c2410_dma_call_op(chan,  S3C2410_DMAOP_STOP);
+
+	tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+	tmp |= S3C2410_DMASKTRIG_STOP;
+	//tmp &= ~S3C2410_DMASKTRIG_ON;
+	dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
+
+#if 0
+	/* should also clear interrupts, according to WinCE BSP */
+	tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
+	tmp |= S3C2410_DCON_NORELOAD;
+	dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
+#endif
+
+	/* should stop do this, or should we wait for flush? */
+	chan->state      = S3C2410_DMA_IDLE;
+	chan->load_state = S3C2410_DMALOAD_NONE;
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
+{
+	unsigned long tmp;
+	unsigned int timeout = 0x10000;
+
+	while (timeout-- > 0) {
+		tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+
+		if (!(tmp & S3C2410_DMASKTRIG_ON))
+			return;
+	}
+
+	pr_debug("dma%d: failed to stop?\n", chan->number);
+}
+
+
+/* s3c2410_dma_flush
+ *
+ * stop the channel, and remove all current and pending transfers
+*/
+
+static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
+{
+	struct s3c2410_dma_buf *buf, *next;
+	unsigned long flags;
+
+	pr_debug("%s: chan %p (%d)\n", __FUNCTION__, chan, chan->number);
+
+	dbg_showchan(chan);
+
+	local_irq_save(flags);
+
+	if (chan->state != S3C2410_DMA_IDLE) {
+		pr_debug("%s: stopping channel...\n", __FUNCTION__ );
+		s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP);
+	}
+
+	buf = chan->curr;
+	if (buf == NULL)
+		buf = chan->next;
+
+	chan->curr = chan->next = chan->end = NULL;
+
+	if (buf != NULL) {
+		for ( ; buf != NULL; buf = next) {
+			next = buf->next;
+
+			pr_debug("%s: free buffer %p, next %p\n",
+			       __FUNCTION__, buf, buf->next);
+
+			s3c2410_dma_buffdone(chan, buf, S3C2410_RES_ABORT);
+			s3c2410_dma_freebuf(buf);
+		}
+	}
+
+	dbg_showregs(chan);
+
+	s3c2410_dma_waitforstop(chan);
+
+#if 0
+	/* should also clear interrupts, according to WinCE BSP */
+	{
+		unsigned long tmp;
+
+		tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
+		tmp |= S3C2410_DCON_NORELOAD;
+		dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
+	}
+#endif
+
+	dbg_showregs(chan);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+int
+s3c2410_dma_started(struct s3c2410_dma_chan *chan)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	dbg_showchan(chan);
+
+	/* if we've only loaded one buffer onto the channel, then chec
+	 * to see if we have another, and if so, try and load it so when
+	 * the first buffer is finished, the new one will be loaded onto
+	 * the channel */
+
+	if (chan->next != NULL) {
+		if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+
+			if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+				pr_debug("%s: buff not yet loaded, no more todo\n",
+					 __FUNCTION__);
+			} else {
+				chan->load_state = S3C2410_DMALOAD_1RUNNING;
+				s3c2410_dma_loadbuffer(chan, chan->next);
+			}
+
+		} else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
+			s3c2410_dma_loadbuffer(chan, chan->next);
+		}
+	}
+
+
+	local_irq_restore(flags);
+
+	return 0;
+
+}
+
+int
+s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op)
+{
+	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	switch (op) {
+	case S3C2410_DMAOP_START:
+		return s3c2410_dma_start(chan);
+
+	case S3C2410_DMAOP_STOP:
+		return s3c2410_dma_dostop(chan);
+
+	case S3C2410_DMAOP_PAUSE:
+	case S3C2410_DMAOP_RESUME:
+		return -ENOENT;
+
+	case S3C2410_DMAOP_FLUSH:
+		return s3c2410_dma_flush(chan);
+
+	case S3C2410_DMAOP_STARTED:
+		return s3c2410_dma_started(chan);
+
+	case S3C2410_DMAOP_TIMEOUT:
+		return 0;
+
+	}
+
+	return -ENOENT;      /* unknown, don't bother */
+}
+
+EXPORT_SYMBOL(s3c2410_dma_ctrl);
+
+/* DMA configuration for each channel
+ *
+ * DISRCC -> source of the DMA (AHB,APB)
+ * DISRC  -> source address of the DMA
+ * DIDSTC -> destination of the DMA (AHB,APD)
+ * DIDST  -> destination address of the DMA
+*/
+
+/* s3c2410_dma_config
+ *
+ * xfersize:     size of unit in bytes (1,2,4)
+ * dcon:         base value of the DCONx register
+*/
+
+int s3c2410_dma_config(dmach_t channel,
+		       int xferunit,
+		       int dcon)
+{
+	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+	pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
+		 __FUNCTION__, channel, xferunit, dcon);
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	pr_debug("%s: Initial dcon is %08x\n", __FUNCTION__, dcon);
+
+	dcon |= chan->dcon & dma_sel.dcon_mask;
+
+	pr_debug("%s: New dcon is %08x\n", __FUNCTION__, dcon);
+
+	switch (xferunit) {
+	case 1:
+		dcon |= S3C2410_DCON_BYTE;
+		break;
+
+	case 2:
+		dcon |= S3C2410_DCON_HALFWORD;
+		break;
+
+	case 4:
+		dcon |= S3C2410_DCON_WORD;
+		break;
+
+	default:
+		pr_debug("%s: bad transfer size %d\n", __FUNCTION__, xferunit);
+		return -EINVAL;
+	}
+
+	dcon |= S3C2410_DCON_HWTRIG;
+	dcon |= S3C2410_DCON_INTREQ;
+
+	pr_debug("%s: dcon now %08x\n", __FUNCTION__, dcon);
+
+	chan->dcon = dcon;
+	chan->xfer_unit = xferunit;
+
+	return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_config);
+
+int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
+{
+	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags);
+
+	chan->flags = flags;
+
+	return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_setflags);
+
+
+/* do we need to protect the settings of the fields from
+ * irq?
+*/
+
+int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn)
+{
+	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn);
+
+	chan->op_fn = rtn;
+
+	return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_set_opfn);
+
+int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
+{
+	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn);
+
+	chan->callback_fn = rtn;
+
+	return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
+
+/* s3c2410_dma_devconfig
+ *
+ * configure the dma source/destination hardware type and address
+ *
+ * source:    S3C2410_DMASRC_HW: source is hardware
+ *            S3C2410_DMASRC_MEM: source is memory
+ *
+ * hwcfg:     the value for xxxSTCn register,
+ *            bit 0: 0=increment pointer, 1=leave pointer
+ *            bit 1: 0=soucre is AHB, 1=soucre is APB
+ *
+ * devaddr:   physical address of the source
+*/
+
+int s3c2410_dma_devconfig(int channel,
+			  enum s3c2410_dmasrc source,
+			  int hwcfg,
+			  unsigned long devaddr)
+{
+	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n",
+		 __FUNCTION__, (int)source, hwcfg, devaddr);
+
+	chan->source = source;
+	chan->dev_addr = devaddr;
+
+	switch (source) {
+	case S3C2410_DMASRC_HW:
+		/* source is hardware */
+		pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
+			 __FUNCTION__, devaddr, hwcfg);
+		dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);
+		dma_wrreg(chan, S3C2410_DMA_DISRC,  devaddr);
+		dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
+
+		chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
+		return 0;
+
+	case S3C2410_DMASRC_MEM:
+		/* source is memory */
+		pr_debug( "%s: mem source, devaddr=%08lx, hwcfg=%d\n",
+			  __FUNCTION__, devaddr, hwcfg);
+		dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
+		dma_wrreg(chan, S3C2410_DMA_DIDST,  devaddr);
+		dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
+
+		chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
+		return 0;
+	}
+
+	printk(KERN_ERR "dma%d: invalid source type (%d)\n", channel, source);
+	return -EINVAL;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_devconfig);
+
+/* s3c2410_dma_getposition
+ *
+ * returns the current transfer points for the dma source and destination
+*/
+
+int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
+{
+ 	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	if (src != NULL)
+ 		*src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
+
+ 	if (dst != NULL)
+ 		*dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
+
+ 	return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_getposition);
+
+
+/* system device class */
+
+#ifdef CONFIG_PM
+
+static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
+{
+	struct s3c2410_dma_chan *cp = container_of(dev, struct s3c2410_dma_chan, dev);
+
+	printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
+
+	if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) {
+		/* the dma channel is still working, which is probably
+		 * a bad thing to do over suspend/resume. We stop the
+		 * channel and assume that the client is either going to
+		 * retry after resume, or that it is broken.
+		 */
+
+		printk(KERN_INFO "dma: stopping channel %d due to suspend\n",
+		       cp->number);
+
+		s3c2410_dma_dostop(cp);
+	}
+
+	return 0;
+}
+
+static int s3c2410_dma_resume(struct sys_device *dev)
+{
+	return 0;
+}
+
+#else
+#define s3c2410_dma_suspend NULL
+#define s3c2410_dma_resume  NULL
+#endif /* CONFIG_PM */
+
+struct sysdev_class dma_sysclass = {
+	set_kset_name("s3c24xx-dma"),
+	.suspend	= s3c2410_dma_suspend,
+	.resume		= s3c2410_dma_resume,
+};
+
+/* kmem cache implementation */
+
+static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long f)
+{
+	memset(p, 0, sizeof(struct s3c2410_dma_buf));
+}
+
+/* initialisation code */
+
+int __init s3c24xx_dma_sysclass_init(void)
+{
+	int ret = sysdev_class_register(&dma_sysclass);
+
+	if (ret != 0)
+		printk(KERN_ERR "dma sysclass registration failed\n");
+
+	return ret;
+}
+
+core_initcall(s3c24xx_dma_sysclass_init);
+
+int __init s3c24xx_dma_sysdev_register(void)
+{
+	struct s3c2410_dma_chan *cp = s3c2410_chans;
+	int channel, ret;
+
+	for (channel = 0; channel < dma_channels; cp++, channel++) {
+		cp->dev.cls = &dma_sysclass;
+		cp->dev.id  = channel;
+		ret = sysdev_register(&cp->dev);
+
+		if (ret) {
+			printk(KERN_ERR "error registering dev for dma %d\n",
+			       channel);
+ 			return ret;
+		}
+	}
+
+	return 0;
+}
+
+late_initcall(s3c24xx_dma_sysdev_register);
+
+int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq,
+			    unsigned int stride)
+{
+	struct s3c2410_dma_chan *cp;
+	int channel;
+	int ret;
+
+	printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n");
+
+	dma_channels = channels;
+
+	dma_base = ioremap(S3C24XX_PA_DMA, stride * channels);
+	if (dma_base == NULL) {
+		printk(KERN_ERR "dma failed to remap register block\n");
+		return -ENOMEM;
+	}
+
+	dma_kmem = kmem_cache_create("dma_desc",
+				     sizeof(struct s3c2410_dma_buf), 0,
+				     SLAB_HWCACHE_ALIGN,
+				     s3c2410_dma_cache_ctor, NULL);
+
+	if (dma_kmem == NULL) {
+		printk(KERN_ERR "dma failed to make kmem cache\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	for (channel = 0; channel < channels;  channel++) {
+		cp = &s3c2410_chans[channel];
+
+		memset(cp, 0, sizeof(struct s3c2410_dma_chan));
+
+		/* dma channel irqs are in order.. */
+		cp->number = channel;
+		cp->irq    = channel + irq;
+		cp->regs   = dma_base + (channel * stride);
+
+		/* point current stats somewhere */
+		cp->stats  = &cp->stats_store;
+		cp->stats_store.timeout_shortest = LONG_MAX;
+
+		/* basic channel configuration */
+
+		cp->load_timeout = 1<<18;
+
+		printk("DMA channel %d at %p, irq %d\n",
+		       cp->number, cp->regs, cp->irq);
+	}
+
+	return 0;
+
+ err:
+	kmem_cache_destroy(dma_kmem);
+	iounmap(dma_base);
+	dma_base = NULL;
+	return ret;
+}
+
+int s3c2410_dma_init(void)
+{
+	return s3c24xx_dma_init(4, IRQ_DMA0, 0x40);
+}
+
+static inline int is_channel_valid(unsigned int channel)
+{
+	return (channel & DMA_CH_VALID);
+}
+
+static struct s3c24xx_dma_order *dma_order;
+
+
+/* s3c2410_dma_map_channel()
+ *
+ * turn the virtual channel number into a real, and un-used hardware
+ * channel.
+ *
+ * first, try the dma ordering given to us by either the relevant
+ * dma code, or the board. Then just find the first usable free
+ * channel
+*/
+
+struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
+{
+	struct s3c24xx_dma_order_ch *ord = NULL;
+	struct s3c24xx_dma_map *ch_map;
+	struct s3c2410_dma_chan *dmach;
+	int ch;
+
+	if (dma_sel.map == NULL || channel > dma_sel.map_size)
+		return NULL;
+
+	ch_map = dma_sel.map + channel;
+
+	/* first, try the board mapping */
+
+	if (dma_order) {
+		ord = &dma_order->channels[channel];
+
+		for (ch = 0; ch < dma_channels; ch++) {
+			if (!is_channel_valid(ord->list[ch]))
+				continue;
+
+			if (s3c2410_chans[ord->list[ch]].in_use == 0) {
+				ch = ord->list[ch] & ~DMA_CH_VALID;
+				goto found;
+			}
+		}
+
+		if (ord->flags & DMA_CH_NEVER)
+			return NULL;
+	}
+
+	/* second, search the channel map for first free */
+
+	for (ch = 0; ch < dma_channels; ch++) {
+		if (!is_channel_valid(ch_map->channels[ch]))
+			continue;
+
+		if (s3c2410_chans[ch].in_use == 0) {
+			printk("mapped channel %d to %d\n", channel, ch);
+			break;
+		}
+	}
+
+	if (ch >= dma_channels)
+		return NULL;
+
+	/* update our channel mapping */
+
+ found:
+	dmach = &s3c2410_chans[ch];
+	dma_chan_map[channel] = dmach;
+
+	/* select the channel */
+
+	(dma_sel.select)(dmach, ch_map);
+
+	return dmach;
+}
+
+static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch)
+{
+	return 0;
+}
+
+int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
+{
+	struct s3c24xx_dma_map *nmap;
+	size_t map_sz = sizeof(*nmap) * sel->map_size;
+	int ptr;
+
+	nmap = kmalloc(map_sz, GFP_KERNEL);
+	if (nmap == NULL)
+		return -ENOMEM;
+
+	memcpy(nmap, sel->map, map_sz);
+	memcpy(&dma_sel, sel, sizeof(*sel));
+
+	dma_sel.map = nmap;
+
+	for (ptr = 0; ptr < sel->map_size; ptr++)
+		s3c24xx_dma_check_entry(nmap+ptr, ptr);
+
+	return 0;
+}
+
+int __init s3c24xx_dma_order_set(struct s3c24xx_dma_order *ord)
+{
+	struct s3c24xx_dma_order *nord = dma_order;
+
+	if (nord == NULL)
+		nord = kmalloc(sizeof(struct s3c24xx_dma_order), GFP_KERNEL);
+
+	if (nord == NULL) {
+		printk(KERN_ERR "no memory to store dma channel order\n");
+		return -ENOMEM;
+	}
+
+	dma_order = nord;
+	memcpy(nord, ord, sizeof(struct s3c24xx_dma_order));
+	return 0;
+}
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
new file mode 100644
index 0000000..ec3a09c
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/gpio.c
@@ -0,0 +1,188 @@
+/* linux/arch/arm/plat-s3c24xx/gpio.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX GPIO support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-gpio.h>
+
+void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
+{
+	void __iomem *base = S3C24XX_GPIO_BASE(pin);
+	unsigned long mask;
+	unsigned long con;
+	unsigned long flags;
+
+	if (pin < S3C2410_GPIO_BANKB) {
+		mask = 1 << S3C2410_GPIO_OFFSET(pin);
+	} else {
+		mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
+	}
+
+	switch (function) {
+	case S3C2410_GPIO_LEAVE:
+		mask = 0;
+		function = 0;
+		break;
+
+	case S3C2410_GPIO_INPUT:
+	case S3C2410_GPIO_OUTPUT:
+	case S3C2410_GPIO_SFN2:
+	case S3C2410_GPIO_SFN3:
+		if (pin < S3C2410_GPIO_BANKB) {
+			function -= 1;
+			function &= 1;
+			function <<= S3C2410_GPIO_OFFSET(pin);
+		} else {
+			function &= 3;
+			function <<= S3C2410_GPIO_OFFSET(pin)*2;
+		}
+	}
+
+	/* modify the specified register wwith IRQs off */
+
+	local_irq_save(flags);
+
+	con  = __raw_readl(base + 0x00);
+	con &= ~mask;
+	con |= function;
+
+	__raw_writel(con, base + 0x00);
+
+	local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
+
+unsigned int s3c2410_gpio_getcfg(unsigned int pin)
+{
+	void __iomem *base = S3C24XX_GPIO_BASE(pin);
+	unsigned long val = __raw_readl(base);
+
+	if (pin < S3C2410_GPIO_BANKB) {
+		val >>= S3C2410_GPIO_OFFSET(pin);
+		val &= 1;
+		val += 1;
+	} else {
+		val >>= S3C2410_GPIO_OFFSET(pin)*2;
+		val &= 3;
+	}
+
+	return val | S3C2410_GPIO_INPUT;
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_getcfg);
+
+void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
+{
+	void __iomem *base = S3C24XX_GPIO_BASE(pin);
+	unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+	unsigned long flags;
+	unsigned long up;
+
+	if (pin < S3C2410_GPIO_BANKB)
+		return;
+
+	local_irq_save(flags);
+
+	up = __raw_readl(base + 0x08);
+	up &= ~(1L << offs);
+	up |= to << offs;
+	__raw_writel(up, base + 0x08);
+
+	local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_pullup);
+
+void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
+{
+	void __iomem *base = S3C24XX_GPIO_BASE(pin);
+	unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+	unsigned long flags;
+	unsigned long dat;
+
+	local_irq_save(flags);
+
+	dat = __raw_readl(base + 0x04);
+	dat &= ~(1 << offs);
+	dat |= to << offs;
+	__raw_writel(dat, base + 0x04);
+
+	local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_setpin);
+
+unsigned int s3c2410_gpio_getpin(unsigned int pin)
+{
+	void __iomem *base = S3C24XX_GPIO_BASE(pin);
+	unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+
+	return __raw_readl(base + 0x04) & (1<< offs);
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_getpin);
+
+unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
+{
+	unsigned long flags;
+	unsigned long misccr;
+
+	local_irq_save(flags);
+	misccr = __raw_readl(S3C24XX_MISCCR);
+	misccr &= ~clear;
+	misccr ^= change;
+	__raw_writel(misccr, S3C24XX_MISCCR);
+	local_irq_restore(flags);
+
+	return misccr;
+}
+
+EXPORT_SYMBOL(s3c2410_modify_misccr);
+
+int s3c2410_gpio_getirq(unsigned int pin)
+{
+	if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15)
+		return -1;	/* not valid interrupts */
+
+	if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
+		return -1;	/* not valid pin */
+
+	if (pin < S3C2410_GPF4)
+		return (pin - S3C2410_GPF0) + IRQ_EINT0;
+
+	if (pin < S3C2410_GPG0)
+		return (pin - S3C2410_GPF4) + IRQ_EINT4;
+
+	return (pin - S3C2410_GPG0) + IRQ_EINT8;
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_getirq);
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
new file mode 100644
index 0000000..ce18639
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -0,0 +1,801 @@
+/* linux/arch/arm/plat-s3c24xx/irq.c
+ *
+ * Copyright (c) 2003,2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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
+ *
+ * Changelog:
+ *
+ *   22-Jul-2004  Ben Dooks <ben@simtec.co.uk>
+ *                Fixed compile warnings
+ *
+ *   22-Jul-2004  Roc Wu <cooloney@yahoo.com.cn>
+ *                Fixed s3c_extirq_type
+ *
+ *   21-Jul-2004  Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
+ *                Addition of ADC/TC demux
+ *
+ *   04-Oct-2004  Klaus Fetscher <k.fetscher@fetron.de>
+ *		  Fix for set_irq_type() on low EINT numbers
+ *
+ *   05-Oct-2004  Ben Dooks <ben@simtec.co.uk>
+ *		  Tidy up KF's patch and sort out new release
+ *
+ *   05-Oct-2004  Ben Dooks <ben@simtec.co.uk>
+ *		  Add support for power management controls
+ *
+ *   04-Nov-2004  Ben Dooks
+ *		  Fix standard IRQ wake for EINT0..4 and RTC
+ *
+ *   22-Feb-2005  Ben Dooks
+ *		  Fixed edge-triggering on ADC IRQ
+ *
+ *   28-Jun-2005  Ben Dooks
+ *		  Mark IRQ_LCD valid
+ *
+ *   25-Jul-2005  Ben Dooks
+ *		  Split the S3C2440 IRQ code to seperate file
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/ptrace.h>
+#include <linux/sysdev.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+#include <asm/arch/regs-irq.h>
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+#include <asm/plat-s3c24xx/irq.h>
+
+/* wakeup irq control */
+
+#ifdef CONFIG_PM
+
+/* state for IRQs over sleep */
+
+/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
+ *
+ * set bit to 1 in allow bitfield to enable the wakeup settings on it
+*/
+
+unsigned long s3c_irqwake_intallow	= 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
+unsigned long s3c_irqwake_intmask	= 0xffffffffL;
+unsigned long s3c_irqwake_eintallow	= 0x0000fff0L;
+unsigned long s3c_irqwake_eintmask	= 0xffffffffL;
+
+int
+s3c_irq_wake(unsigned int irqno, unsigned int state)
+{
+	unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
+
+	if (!(s3c_irqwake_intallow & irqbit))
+		return -ENOENT;
+
+	printk(KERN_INFO "wake %s for irq %d\n",
+	       state ? "enabled" : "disabled", irqno);
+
+	if (!state)
+		s3c_irqwake_intmask |= irqbit;
+	else
+		s3c_irqwake_intmask &= ~irqbit;
+
+	return 0;
+}
+
+static int
+s3c_irqext_wake(unsigned int irqno, unsigned int state)
+{
+	unsigned long bit = 1L << (irqno - EXTINT_OFF);
+
+	if (!(s3c_irqwake_eintallow & bit))
+		return -ENOENT;
+
+	printk(KERN_INFO "wake %s for irq %d\n",
+	       state ? "enabled" : "disabled", irqno);
+
+	if (!state)
+		s3c_irqwake_eintmask |= bit;
+	else
+		s3c_irqwake_eintmask &= ~bit;
+
+	return 0;
+}
+
+#else
+#define s3c_irqext_wake NULL
+#define s3c_irq_wake NULL
+#endif
+
+
+static void
+s3c_irq_mask(unsigned int irqno)
+{
+	unsigned long mask;
+
+	irqno -= IRQ_EINT0;
+
+	mask = __raw_readl(S3C2410_INTMSK);
+	mask |= 1UL << irqno;
+	__raw_writel(mask, S3C2410_INTMSK);
+}
+
+static inline void
+s3c_irq_ack(unsigned int irqno)
+{
+	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+
+	__raw_writel(bitval, S3C2410_SRCPND);
+	__raw_writel(bitval, S3C2410_INTPND);
+}
+
+static inline void
+s3c_irq_maskack(unsigned int irqno)
+{
+	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned long mask;
+
+	mask = __raw_readl(S3C2410_INTMSK);
+	__raw_writel(mask|bitval, S3C2410_INTMSK);
+
+	__raw_writel(bitval, S3C2410_SRCPND);
+	__raw_writel(bitval, S3C2410_INTPND);
+}
+
+
+static void
+s3c_irq_unmask(unsigned int irqno)
+{
+	unsigned long mask;
+
+	if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
+		irqdbf2("s3c_irq_unmask %d\n", irqno);
+
+	irqno -= IRQ_EINT0;
+
+	mask = __raw_readl(S3C2410_INTMSK);
+	mask &= ~(1UL << irqno);
+	__raw_writel(mask, S3C2410_INTMSK);
+}
+
+struct irq_chip s3c_irq_level_chip = {
+	.name		= "s3c-level",
+	.ack		= s3c_irq_maskack,
+	.mask		= s3c_irq_mask,
+	.unmask		= s3c_irq_unmask,
+	.set_wake	= s3c_irq_wake
+};
+
+static struct irq_chip s3c_irq_chip = {
+	.name		= "s3c",
+	.ack		= s3c_irq_ack,
+	.mask		= s3c_irq_mask,
+	.unmask		= s3c_irq_unmask,
+	.set_wake	= s3c_irq_wake
+};
+
+static void
+s3c_irqext_mask(unsigned int irqno)
+{
+	unsigned long mask;
+
+	irqno -= EXTINT_OFF;
+
+	mask = __raw_readl(S3C24XX_EINTMASK);
+	mask |= ( 1UL << irqno);
+	__raw_writel(mask, S3C24XX_EINTMASK);
+}
+
+static void
+s3c_irqext_ack(unsigned int irqno)
+{
+	unsigned long req;
+	unsigned long bit;
+	unsigned long mask;
+
+	bit = 1UL << (irqno - EXTINT_OFF);
+
+	mask = __raw_readl(S3C24XX_EINTMASK);
+
+	__raw_writel(bit, S3C24XX_EINTPEND);
+
+	req = __raw_readl(S3C24XX_EINTPEND);
+	req &= ~mask;
+
+	/* not sure if we should be acking the parent irq... */
+
+	if (irqno <= IRQ_EINT7 ) {
+		if ((req & 0xf0) == 0)
+			s3c_irq_ack(IRQ_EINT4t7);
+	} else {
+		if ((req >> 8) == 0)
+			s3c_irq_ack(IRQ_EINT8t23);
+	}
+}
+
+static void
+s3c_irqext_unmask(unsigned int irqno)
+{
+	unsigned long mask;
+
+	irqno -= EXTINT_OFF;
+
+	mask = __raw_readl(S3C24XX_EINTMASK);
+	mask &= ~( 1UL << irqno);
+	__raw_writel(mask, S3C24XX_EINTMASK);
+}
+
+int
+s3c_irqext_type(unsigned int irq, unsigned int type)
+{
+	void __iomem *extint_reg;
+	void __iomem *gpcon_reg;
+	unsigned long gpcon_offset, extint_offset;
+	unsigned long newvalue = 0, value;
+
+	if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
+	{
+		gpcon_reg = S3C2410_GPFCON;
+		extint_reg = S3C24XX_EXTINT0;
+		gpcon_offset = (irq - IRQ_EINT0) * 2;
+		extint_offset = (irq - IRQ_EINT0) * 4;
+	}
+	else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
+	{
+		gpcon_reg = S3C2410_GPFCON;
+		extint_reg = S3C24XX_EXTINT0;
+		gpcon_offset = (irq - (EXTINT_OFF)) * 2;
+		extint_offset = (irq - (EXTINT_OFF)) * 4;
+	}
+	else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
+	{
+		gpcon_reg = S3C2410_GPGCON;
+		extint_reg = S3C24XX_EXTINT1;
+		gpcon_offset = (irq - IRQ_EINT8) * 2;
+		extint_offset = (irq - IRQ_EINT8) * 4;
+	}
+	else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
+	{
+		gpcon_reg = S3C2410_GPGCON;
+		extint_reg = S3C24XX_EXTINT2;
+		gpcon_offset = (irq - IRQ_EINT8) * 2;
+		extint_offset = (irq - IRQ_EINT16) * 4;
+	} else
+		return -1;
+
+	/* Set the GPIO to external interrupt mode */
+	value = __raw_readl(gpcon_reg);
+	value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
+	__raw_writel(value, gpcon_reg);
+
+	/* Set the external interrupt to pointed trigger type */
+	switch (type)
+	{
+		case IRQT_NOEDGE:
+			printk(KERN_WARNING "No edge setting!\n");
+			break;
+
+		case IRQT_RISING:
+			newvalue = S3C2410_EXTINT_RISEEDGE;
+			break;
+
+		case IRQT_FALLING:
+			newvalue = S3C2410_EXTINT_FALLEDGE;
+			break;
+
+		case IRQT_BOTHEDGE:
+			newvalue = S3C2410_EXTINT_BOTHEDGE;
+			break;
+
+		case IRQT_LOW:
+			newvalue = S3C2410_EXTINT_LOWLEV;
+			break;
+
+		case IRQT_HIGH:
+			newvalue = S3C2410_EXTINT_HILEV;
+			break;
+
+		default:
+			printk(KERN_ERR "No such irq type %d", type);
+			return -1;
+	}
+
+	value = __raw_readl(extint_reg);
+	value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
+	__raw_writel(value, extint_reg);
+
+	return 0;
+}
+
+static struct irq_chip s3c_irqext_chip = {
+	.name		= "s3c-ext",
+	.mask		= s3c_irqext_mask,
+	.unmask		= s3c_irqext_unmask,
+	.ack		= s3c_irqext_ack,
+	.set_type	= s3c_irqext_type,
+	.set_wake	= s3c_irqext_wake
+};
+
+static struct irq_chip s3c_irq_eint0t4 = {
+	.name		= "s3c-ext0",
+	.ack		= s3c_irq_ack,
+	.mask		= s3c_irq_mask,
+	.unmask		= s3c_irq_unmask,
+	.set_wake	= s3c_irq_wake,
+	.set_type	= s3c_irqext_type,
+};
+
+/* mask values for the parent registers for each of the interrupt types */
+
+#define INTMSK_UART0	 (1UL << (IRQ_UART0 - IRQ_EINT0))
+#define INTMSK_UART1	 (1UL << (IRQ_UART1 - IRQ_EINT0))
+#define INTMSK_UART2	 (1UL << (IRQ_UART2 - IRQ_EINT0))
+#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
+
+
+/* UART0 */
+
+static void
+s3c_irq_uart0_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
+}
+
+static void
+s3c_irq_uart0_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_UART0);
+}
+
+static void
+s3c_irq_uart0_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
+}
+
+static struct irq_chip s3c_irq_uart0 = {
+	.name		= "s3c-uart0",
+	.mask		= s3c_irq_uart0_mask,
+	.unmask		= s3c_irq_uart0_unmask,
+	.ack		= s3c_irq_uart0_ack,
+};
+
+/* UART1 */
+
+static void
+s3c_irq_uart1_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
+}
+
+static void
+s3c_irq_uart1_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_UART1);
+}
+
+static void
+s3c_irq_uart1_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
+}
+
+static struct irq_chip s3c_irq_uart1 = {
+	.name		= "s3c-uart1",
+	.mask		= s3c_irq_uart1_mask,
+	.unmask		= s3c_irq_uart1_unmask,
+	.ack		= s3c_irq_uart1_ack,
+};
+
+/* UART2 */
+
+static void
+s3c_irq_uart2_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
+}
+
+static void
+s3c_irq_uart2_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_UART2);
+}
+
+static void
+s3c_irq_uart2_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
+}
+
+static struct irq_chip s3c_irq_uart2 = {
+	.name		= "s3c-uart2",
+	.mask		= s3c_irq_uart2_mask,
+	.unmask		= s3c_irq_uart2_unmask,
+	.ack		= s3c_irq_uart2_ack,
+};
+
+/* ADC and Touchscreen */
+
+static void
+s3c_irq_adc_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
+}
+
+static void
+s3c_irq_adc_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
+}
+
+static void
+s3c_irq_adc_ack(unsigned int irqno)
+{
+	s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
+}
+
+static struct irq_chip s3c_irq_adc = {
+	.name		= "s3c-adc",
+	.mask		= s3c_irq_adc_mask,
+	.unmask		= s3c_irq_adc_unmask,
+	.ack		= s3c_irq_adc_ack,
+};
+
+/* irq demux for adc */
+static void s3c_irq_demux_adc(unsigned int irq,
+			      struct irq_desc *desc)
+{
+	unsigned int subsrc, submsk;
+	unsigned int offset = 9;
+	struct irq_desc *mydesc;
+
+	/* read the current pending interrupts, and the mask
+	 * for what it is available */
+
+	subsrc = __raw_readl(S3C2410_SUBSRCPND);
+	submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+	subsrc &= ~submsk;
+	subsrc >>= offset;
+	subsrc &= 3;
+
+	if (subsrc != 0) {
+		if (subsrc & 1) {
+			mydesc = irq_desc + IRQ_TC;
+			desc_handle_irq(IRQ_TC, mydesc);
+		}
+		if (subsrc & 2) {
+			mydesc = irq_desc + IRQ_ADC;
+			desc_handle_irq(IRQ_ADC, mydesc);
+		}
+	}
+}
+
+static void s3c_irq_demux_uart(unsigned int start)
+{
+	unsigned int subsrc, submsk;
+	unsigned int offset = start - IRQ_S3CUART_RX0;
+	struct irq_desc *desc;
+
+	/* read the current pending interrupts, and the mask
+	 * for what it is available */
+
+	subsrc = __raw_readl(S3C2410_SUBSRCPND);
+	submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+	irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
+		start, offset, subsrc, submsk);
+
+	subsrc &= ~submsk;
+	subsrc >>= offset;
+	subsrc &= 7;
+
+	if (subsrc != 0) {
+		desc = irq_desc + start;
+
+		if (subsrc & 1)
+			desc_handle_irq(start, desc);
+
+		desc++;
+
+		if (subsrc & 2)
+			desc_handle_irq(start+1, desc);
+
+		desc++;
+
+		if (subsrc & 4)
+			desc_handle_irq(start+2, desc);
+	}
+}
+
+/* uart demux entry points */
+
+static void
+s3c_irq_demux_uart0(unsigned int irq,
+		    struct irq_desc *desc)
+{
+	irq = irq;
+	s3c_irq_demux_uart(IRQ_S3CUART_RX0);
+}
+
+static void
+s3c_irq_demux_uart1(unsigned int irq,
+		    struct irq_desc *desc)
+{
+	irq = irq;
+	s3c_irq_demux_uart(IRQ_S3CUART_RX1);
+}
+
+static void
+s3c_irq_demux_uart2(unsigned int irq,
+		    struct irq_desc *desc)
+{
+	irq = irq;
+	s3c_irq_demux_uart(IRQ_S3CUART_RX2);
+}
+
+static void
+s3c_irq_demux_extint8(unsigned int irq,
+		      struct irq_desc *desc)
+{
+	unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
+	unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
+
+	eintpnd &= ~eintmsk;
+	eintpnd &= ~0xff;	/* ignore lower irqs */
+
+	/* we may as well handle all the pending IRQs here */
+
+	while (eintpnd) {
+		irq = __ffs(eintpnd);
+		eintpnd &= ~(1<<irq);
+
+		irq += (IRQ_EINT4 - 4);
+		desc_handle_irq(irq, irq_desc + irq);
+	}
+
+}
+
+static void
+s3c_irq_demux_extint4t7(unsigned int irq,
+			struct irq_desc *desc)
+{
+	unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
+	unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
+
+	eintpnd &= ~eintmsk;
+	eintpnd &= 0xff;	/* only lower irqs */
+
+	/* we may as well handle all the pending IRQs here */
+
+	while (eintpnd) {
+		irq = __ffs(eintpnd);
+		eintpnd &= ~(1<<irq);
+
+		irq += (IRQ_EINT4 - 4);
+
+		desc_handle_irq(irq, irq_desc + irq);
+	}
+}
+
+#ifdef CONFIG_PM
+
+static struct sleep_save irq_save[] = {
+	SAVE_ITEM(S3C2410_INTMSK),
+	SAVE_ITEM(S3C2410_INTSUBMSK),
+};
+
+/* the extint values move between the s3c2410/s3c2440 and the s3c2412
+ * so we use an array to hold them, and to calculate the address of
+ * the register at run-time
+*/
+
+static unsigned long save_extint[3];
+static unsigned long save_eintflt[4];
+static unsigned long save_eintmask;
+
+int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+		save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
+
+	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+		save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
+
+	s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+	save_eintmask = __raw_readl(S3C24XX_EINTMASK);
+
+	return 0;
+}
+
+int s3c24xx_irq_resume(struct sys_device *dev)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+		__raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
+
+	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+		__raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
+
+	s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+	__raw_writel(save_eintmask, S3C24XX_EINTMASK);
+
+	return 0;
+}
+
+#else
+#define s3c24xx_irq_suspend NULL
+#define s3c24xx_irq_resume  NULL
+#endif
+
+/* s3c24xx_init_irq
+ *
+ * Initialise S3C2410 IRQ system
+*/
+
+void __init s3c24xx_init_irq(void)
+{
+	unsigned long pend;
+	unsigned long last;
+	int irqno;
+	int i;
+
+	irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
+
+	/* first, clear all interrupts pending... */
+
+	last = 0;
+	for (i = 0; i < 4; i++) {
+		pend = __raw_readl(S3C24XX_EINTPEND);
+
+		if (pend == 0 || pend == last)
+			break;
+
+		__raw_writel(pend, S3C24XX_EINTPEND);
+		printk("irq: clearing pending ext status %08x\n", (int)pend);
+		last = pend;
+	}
+
+	last = 0;
+	for (i = 0; i < 4; i++) {
+		pend = __raw_readl(S3C2410_INTPND);
+
+		if (pend == 0 || pend == last)
+			break;
+
+		__raw_writel(pend, S3C2410_SRCPND);
+		__raw_writel(pend, S3C2410_INTPND);
+		printk("irq: clearing pending status %08x\n", (int)pend);
+		last = pend;
+	}
+
+	last = 0;
+	for (i = 0; i < 4; i++) {
+		pend = __raw_readl(S3C2410_SUBSRCPND);
+
+		if (pend == 0 || pend == last)
+			break;
+
+		printk("irq: clearing subpending status %08x\n", (int)pend);
+		__raw_writel(pend, S3C2410_SUBSRCPND);
+		last = pend;
+	}
+
+	/* register the main interrupts */
+
+	irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
+
+	for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
+		/* set all the s3c2410 internal irqs */
+
+		switch (irqno) {
+			/* deal with the special IRQs (cascaded) */
+
+		case IRQ_EINT4t7:
+		case IRQ_EINT8t23:
+		case IRQ_UART0:
+		case IRQ_UART1:
+		case IRQ_UART2:
+		case IRQ_ADCPARENT:
+			set_irq_chip(irqno, &s3c_irq_level_chip);
+			set_irq_handler(irqno, handle_level_irq);
+			break;
+
+		case IRQ_RESERVED6:
+		case IRQ_RESERVED24:
+			/* no IRQ here */
+			break;
+
+		default:
+			//irqdbf("registering irq %d (s3c irq)\n", irqno);
+			set_irq_chip(irqno, &s3c_irq_chip);
+			set_irq_handler(irqno, handle_edge_irq);
+			set_irq_flags(irqno, IRQF_VALID);
+		}
+	}
+
+	/* setup the cascade irq handlers */
+
+	set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
+	set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
+
+	set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
+	set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
+	set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
+	set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
+
+	/* external interrupts */
+
+	for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
+		irqdbf("registering irq %d (ext int)\n", irqno);
+		set_irq_chip(irqno, &s3c_irq_eint0t4);
+		set_irq_handler(irqno, handle_edge_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
+		irqdbf("registering irq %d (extended s3c irq)\n", irqno);
+		set_irq_chip(irqno, &s3c_irqext_chip);
+		set_irq_handler(irqno, handle_edge_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	/* register the uart interrupts */
+
+	irqdbf("s3c2410: registering external interrupts\n");
+
+	for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
+		irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
+		set_irq_chip(irqno, &s3c_irq_uart0);
+		set_irq_handler(irqno, handle_level_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
+		irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
+		set_irq_chip(irqno, &s3c_irq_uart1);
+		set_irq_handler(irqno, handle_level_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
+		irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
+		set_irq_chip(irqno, &s3c_irq_uart2);
+		set_irq_handler(irqno, handle_level_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
+		irqdbf("registering irq %d (s3c adc irq)\n", irqno);
+		set_irq_chip(irqno, &s3c_irq_adc);
+		set_irq_handler(irqno, handle_edge_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	irqdbf("s3c2410: registered interrupt handlers\n");
+}
diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/plat-s3c24xx/pm-simtec.c
similarity index 94%
rename from arch/arm/mach-s3c2410/pm-simtec.c
rename to arch/arm/plat-s3c24xx/pm-simtec.c
index 619133e..bd965f2 100644
--- a/arch/arm/mach-s3c2410/pm-simtec.c
+++ b/arch/arm/plat-s3c24xx/pm-simtec.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/pm-simtec.c
+/* linux/arch/arm/plat-s3c24xx/pm-simtec.c
  *
  * Copyright (c) 2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -32,7 +32,7 @@
 
 #include <asm/mach-types.h>
 
-#include "pm.h"
+#include <asm/plat-s3c24xx/pm.h>
 
 #define COPYRIGHT ", (c) 2005 Simtec Electronics"
 
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
new file mode 100644
index 0000000..ecf68d6
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -0,0 +1,659 @@
+/* linux/arch/arm/plat-s3c24xx/pm.c
+ *
+ * Copyright (c) 2004,2006 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX Power Manager (Suspend-To-RAM) support
+ *
+ * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information
+ *
+ * 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
+ *
+ * Parts based on arch/arm/mach-pxa/pm.c
+ *
+ * Thanks to Dimitry Andric for debugging
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+#include <linux/crc32.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-irq.h>
+
+#include <asm/mach/time.h>
+
+#include <asm/plat-s3c24xx/pm.h>
+
+/* for external use */
+
+unsigned long s3c_pm_flags;
+
+#define PFX "s3c24xx-pm: "
+
+static struct sleep_save core_save[] = {
+	SAVE_ITEM(S3C2410_LOCKTIME),
+	SAVE_ITEM(S3C2410_CLKCON),
+
+	/* we restore the timings here, with the proviso that the board
+	 * brings the system up in an slower, or equal frequency setting
+	 * to the original system.
+	 *
+	 * if we cannot guarantee this, then things are going to go very
+	 * wrong here, as we modify the refresh and both pll settings.
+	 */
+
+	SAVE_ITEM(S3C2410_BWSCON),
+	SAVE_ITEM(S3C2410_BANKCON0),
+	SAVE_ITEM(S3C2410_BANKCON1),
+	SAVE_ITEM(S3C2410_BANKCON2),
+	SAVE_ITEM(S3C2410_BANKCON3),
+	SAVE_ITEM(S3C2410_BANKCON4),
+	SAVE_ITEM(S3C2410_BANKCON5),
+
+	SAVE_ITEM(S3C2410_CLKDIVN),
+	SAVE_ITEM(S3C2410_MPLLCON),
+	SAVE_ITEM(S3C2410_UPLLCON),
+	SAVE_ITEM(S3C2410_CLKSLOW),
+	SAVE_ITEM(S3C2410_REFRESH),
+};
+
+static struct sleep_save gpio_save[] = {
+	SAVE_ITEM(S3C2410_GPACON),
+	SAVE_ITEM(S3C2410_GPADAT),
+
+	SAVE_ITEM(S3C2410_GPBCON),
+	SAVE_ITEM(S3C2410_GPBDAT),
+	SAVE_ITEM(S3C2410_GPBUP),
+
+	SAVE_ITEM(S3C2410_GPCCON),
+	SAVE_ITEM(S3C2410_GPCDAT),
+	SAVE_ITEM(S3C2410_GPCUP),
+
+	SAVE_ITEM(S3C2410_GPDCON),
+	SAVE_ITEM(S3C2410_GPDDAT),
+	SAVE_ITEM(S3C2410_GPDUP),
+
+	SAVE_ITEM(S3C2410_GPECON),
+	SAVE_ITEM(S3C2410_GPEDAT),
+	SAVE_ITEM(S3C2410_GPEUP),
+
+	SAVE_ITEM(S3C2410_GPFCON),
+	SAVE_ITEM(S3C2410_GPFDAT),
+	SAVE_ITEM(S3C2410_GPFUP),
+
+	SAVE_ITEM(S3C2410_GPGCON),
+	SAVE_ITEM(S3C2410_GPGDAT),
+	SAVE_ITEM(S3C2410_GPGUP),
+
+	SAVE_ITEM(S3C2410_GPHCON),
+	SAVE_ITEM(S3C2410_GPHDAT),
+	SAVE_ITEM(S3C2410_GPHUP),
+
+	SAVE_ITEM(S3C2410_DCLKCON),
+};
+
+#ifdef CONFIG_S3C2410_PM_DEBUG
+
+#define SAVE_UART(va) \
+	SAVE_ITEM((va) + S3C2410_ULCON), \
+	SAVE_ITEM((va) + S3C2410_UCON), \
+	SAVE_ITEM((va) + S3C2410_UFCON), \
+	SAVE_ITEM((va) + S3C2410_UMCON), \
+	SAVE_ITEM((va) + S3C2410_UBRDIV)
+
+static struct sleep_save uart_save[] = {
+	SAVE_UART(S3C24XX_VA_UART0),
+	SAVE_UART(S3C24XX_VA_UART1),
+#ifndef CONFIG_CPU_S3C2400
+	SAVE_UART(S3C24XX_VA_UART2),
+#endif
+};
+
+/* debug
+ *
+ * we send the debug to printascii() to allow it to be seen if the
+ * system never wakes up from the sleep
+*/
+
+extern void printascii(const char *);
+
+void pm_dbg(const char *fmt, ...)
+{
+	va_list va;
+	char buff[256];
+
+	va_start(va, fmt);
+	vsprintf(buff, fmt, va);
+	va_end(va);
+
+	printascii(buff);
+}
+
+static void s3c2410_pm_debug_init(void)
+{
+	unsigned long tmp = __raw_readl(S3C2410_CLKCON);
+
+	/* re-start uart clocks */
+	tmp |= S3C2410_CLKCON_UART0;
+	tmp |= S3C2410_CLKCON_UART1;
+	tmp |= S3C2410_CLKCON_UART2;
+
+	__raw_writel(tmp, S3C2410_CLKCON);
+	udelay(10);
+}
+
+#define DBG(fmt...) pm_dbg(fmt)
+#else
+#define DBG(fmt...) printk(KERN_DEBUG fmt)
+
+#define s3c2410_pm_debug_init() do { } while(0)
+
+static struct sleep_save uart_save[] = {};
+#endif
+
+#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0
+
+/* suspend checking code...
+ *
+ * this next area does a set of crc checks over all the installed
+ * memory, so the system can verify if the resume was ok.
+ *
+ * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
+ * increasing it will mean that the area corrupted will be less easy to spot,
+ * and reducing the size will cause the CRC save area to grow
+*/
+
+#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024)
+
+static u32 crc_size;	/* size needed for the crc block */
+static u32 *crcs;	/* allocated over suspend/resume */
+
+typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
+
+/* s3c2410_pm_run_res
+ *
+ * go thorugh the given resource list, and look for system ram
+*/
+
+static void s3c2410_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
+{
+	while (ptr != NULL) {
+		if (ptr->child != NULL)
+			s3c2410_pm_run_res(ptr->child, fn, arg);
+
+		if ((ptr->flags & IORESOURCE_MEM) &&
+		    strcmp(ptr->name, "System RAM") == 0) {
+			DBG("Found system RAM at %08lx..%08lx\n",
+			    ptr->start, ptr->end);
+			arg = (fn)(ptr, arg);
+		}
+
+		ptr = ptr->sibling;
+	}
+}
+
+static void s3c2410_pm_run_sysram(run_fn_t fn, u32 *arg)
+{
+	s3c2410_pm_run_res(&iomem_resource, fn, arg);
+}
+
+static u32 *s3c2410_pm_countram(struct resource *res, u32 *val)
+{
+	u32 size = (u32)(res->end - res->start)+1;
+
+	size += CHECK_CHUNKSIZE-1;
+	size /= CHECK_CHUNKSIZE;
+
+	DBG("Area %08lx..%08lx, %d blocks\n", res->start, res->end, size);
+
+	*val += size * sizeof(u32);
+	return val;
+}
+
+/* s3c2410_pm_prepare_check
+ *
+ * prepare the necessary information for creating the CRCs. This
+ * must be done before the final save, as it will require memory
+ * allocating, and thus touching bits of the kernel we do not
+ * know about.
+*/
+
+static void s3c2410_pm_check_prepare(void)
+{
+	crc_size = 0;
+
+	s3c2410_pm_run_sysram(s3c2410_pm_countram, &crc_size);
+
+	DBG("s3c2410_pm_prepare_check: %u checks needed\n", crc_size);
+
+	crcs = kmalloc(crc_size+4, GFP_KERNEL);
+	if (crcs == NULL)
+		printk(KERN_ERR "Cannot allocated CRC save area\n");
+}
+
+static u32 *s3c2410_pm_makecheck(struct resource *res, u32 *val)
+{
+	unsigned long addr, left;
+
+	for (addr = res->start; addr < res->end;
+	     addr += CHECK_CHUNKSIZE) {
+		left = res->end - addr;
+
+		if (left > CHECK_CHUNKSIZE)
+			left = CHECK_CHUNKSIZE;
+
+		*val = crc32_le(~0, phys_to_virt(addr), left);
+		val++;
+	}
+
+	return val;
+}
+
+/* s3c2410_pm_check_store
+ *
+ * compute the CRC values for the memory blocks before the final
+ * sleep.
+*/
+
+static void s3c2410_pm_check_store(void)
+{
+	if (crcs != NULL)
+		s3c2410_pm_run_sysram(s3c2410_pm_makecheck, crcs);
+}
+
+/* in_region
+ *
+ * return TRUE if the area defined by ptr..ptr+size contatins the
+ * what..what+whatsz
+*/
+
+static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
+{
+	if ((what+whatsz) < ptr)
+		return 0;
+
+	if (what > (ptr+size))
+		return 0;
+
+	return 1;
+}
+
+static u32 *s3c2410_pm_runcheck(struct resource *res, u32 *val)
+{
+	void *save_at = phys_to_virt(s3c2410_sleep_save_phys);
+	unsigned long addr;
+	unsigned long left;
+	void *ptr;
+	u32 calc;
+
+	for (addr = res->start; addr < res->end;
+	     addr += CHECK_CHUNKSIZE) {
+		left = res->end - addr;
+
+		if (left > CHECK_CHUNKSIZE)
+			left = CHECK_CHUNKSIZE;
+
+		ptr = phys_to_virt(addr);
+
+		if (in_region(ptr, left, crcs, crc_size)) {
+			DBG("skipping %08lx, has crc block in\n", addr);
+			goto skip_check;
+		}
+
+		if (in_region(ptr, left, save_at, 32*4 )) {
+			DBG("skipping %08lx, has save block in\n", addr);
+			goto skip_check;
+		}
+
+		/* calculate and check the checksum */
+
+		calc = crc32_le(~0, ptr, left);
+		if (calc != *val) {
+			printk(KERN_ERR PFX "Restore CRC error at "
+			       "%08lx (%08x vs %08x)\n", addr, calc, *val);
+
+			DBG("Restore CRC error at %08lx (%08x vs %08x)\n",
+			    addr, calc, *val);
+		}
+
+	skip_check:
+		val++;
+	}
+
+	return val;
+}
+
+/* s3c2410_pm_check_restore
+ *
+ * check the CRCs after the restore event and free the memory used
+ * to hold them
+*/
+
+static void s3c2410_pm_check_restore(void)
+{
+	if (crcs != NULL) {
+		s3c2410_pm_run_sysram(s3c2410_pm_runcheck, crcs);
+		kfree(crcs);
+		crcs = NULL;
+	}
+}
+
+#else
+
+#define s3c2410_pm_check_prepare() do { } while(0)
+#define s3c2410_pm_check_restore() do { } while(0)
+#define s3c2410_pm_check_store()   do { } while(0)
+#endif
+
+/* helper functions to save and restore register state */
+
+void s3c2410_pm_do_save(struct sleep_save *ptr, int count)
+{
+	for (; count > 0; count--, ptr++) {
+		ptr->val = __raw_readl(ptr->reg);
+		DBG("saved %p value %08lx\n", ptr->reg, ptr->val);
+	}
+}
+
+/* s3c2410_pm_do_restore
+ *
+ * restore the system from the given list of saved registers
+ *
+ * Note, we do not use DBG() in here, as the system may not have
+ * restore the UARTs state yet
+*/
+
+void s3c2410_pm_do_restore(struct sleep_save *ptr, int count)
+{
+	for (; count > 0; count--, ptr++) {
+		printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
+		       ptr->reg, ptr->val, __raw_readl(ptr->reg));
+
+		__raw_writel(ptr->val, ptr->reg);
+	}
+}
+
+/* s3c2410_pm_do_restore_core
+ *
+ * similar to s3c2410_pm_do_restore_core
+ *
+ * WARNING: Do not put any debug in here that may effect memory or use
+ * peripherals, as things may be changing!
+*/
+
+static void s3c2410_pm_do_restore_core(struct sleep_save *ptr, int count)
+{
+	for (; count > 0; count--, ptr++) {
+		__raw_writel(ptr->val, ptr->reg);
+	}
+}
+
+/* s3c2410_pm_show_resume_irqs
+ *
+ * print any IRQs asserted at resume time (ie, we woke from)
+*/
+
+static void s3c2410_pm_show_resume_irqs(int start, unsigned long which,
+					unsigned long mask)
+{
+	int i;
+
+	which &= ~mask;
+
+	for (i = 0; i <= 31; i++) {
+		if ((which) & (1L<<i)) {
+			DBG("IRQ %d asserted at resume\n", start+i);
+		}
+	}
+}
+
+/* s3c2410_pm_check_resume_pin
+ *
+ * check to see if the pin is configured correctly for sleep mode, and
+ * make any necessary adjustments if it is not
+*/
+
+static void s3c2410_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
+{
+	unsigned long irqstate;
+	unsigned long pinstate;
+	int irq = s3c2410_gpio_getirq(pin);
+
+	if (irqoffs < 4)
+		irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
+	else
+		irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
+
+	pinstate = s3c2410_gpio_getcfg(pin);
+
+	if (!irqstate) {
+		if (pinstate == S3C2410_GPIO_IRQ)
+			DBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
+	} else {
+		if (pinstate == S3C2410_GPIO_IRQ) {
+			DBG("Disabling IRQ %d (pin %d)\n", irq, pin);
+			s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
+		}
+	}
+}
+
+/* s3c2410_pm_configure_extint
+ *
+ * configure all external interrupt pins
+*/
+
+static void s3c2410_pm_configure_extint(void)
+{
+	int pin;
+
+	/* for each of the external interrupts (EINT0..EINT15) we
+	 * need to check wether it is an external interrupt source,
+	 * and then configure it as an input if it is not
+	*/
+
+	for (pin = S3C2410_GPF0; pin <= S3C2410_GPF7; pin++) {
+		s3c2410_pm_check_resume_pin(pin, pin - S3C2410_GPF0);
+	}
+
+	for (pin = S3C2410_GPG0; pin <= S3C2410_GPG7; pin++) {
+		s3c2410_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8);
+	}
+}
+
+void (*pm_cpu_prep)(void);
+void (*pm_cpu_sleep)(void);
+
+#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
+
+/* s3c2410_pm_enter
+ *
+ * central control for sleep/resume process
+*/
+
+static int s3c2410_pm_enter(suspend_state_t state)
+{
+	unsigned long regs_save[16];
+
+	/* ensure the debug is initialised (if enabled) */
+
+	s3c2410_pm_debug_init();
+
+	DBG("s3c2410_pm_enter(%d)\n", state);
+
+	if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
+		printk(KERN_ERR PFX "error: no cpu sleep functions set\n");
+		return -EINVAL;
+	}
+
+	if (state != PM_SUSPEND_MEM) {
+		printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
+		return -EINVAL;
+	}
+
+	/* check if we have anything to wake-up with... bad things seem
+	 * to happen if you suspend with no wakeup (system will often
+	 * require a full power-cycle)
+	*/
+
+	if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
+	    !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
+		printk(KERN_ERR PFX "No sources enabled for wake-up!\n");
+		printk(KERN_ERR PFX "Aborting sleep\n");
+		return -EINVAL;
+	}
+
+	/* prepare check area if configured */
+
+	s3c2410_pm_check_prepare();
+
+	/* store the physical address of the register recovery block */
+
+	s3c2410_sleep_save_phys = virt_to_phys(regs_save);
+
+	DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys);
+
+	/* save all necessary core registers not covered by the drivers */
+
+	s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));
+	s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
+	s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
+
+	/* set the irq configuration for wake */
+
+	s3c2410_pm_configure_extint();
+
+	DBG("sleep: irq wakeup masks: %08lx,%08lx\n",
+	    s3c_irqwake_intmask, s3c_irqwake_eintmask);
+
+	__raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
+	__raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
+
+	/* ack any outstanding external interrupts before we go to sleep */
+
+	__raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
+	__raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
+	__raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
+
+	/* call cpu specific preperation */
+
+	pm_cpu_prep();
+
+	/* flush cache back to ram */
+
+	flush_cache_all();
+
+	s3c2410_pm_check_store();
+
+	/* send the cpu to sleep... */
+
+	__raw_writel(0x00, S3C2410_CLKCON);  /* turn off clocks over sleep */
+
+	/* s3c2410_cpu_save will also act as our return point from when
+	 * we resume as it saves its own register state, so use the return
+	 * code to differentiate return from save and return from sleep */
+
+	if (s3c2410_cpu_save(regs_save) == 0) {
+		flush_cache_all();
+		pm_cpu_sleep();
+	}
+
+	/* restore the cpu state */
+
+	cpu_init();
+
+	/* restore the system state */
+
+	s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+	s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
+	s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
+
+	s3c2410_pm_debug_init();
+
+	/* check what irq (if any) restored the system */
+
+	DBG("post sleep: IRQs 0x%08x, 0x%08x\n",
+	    __raw_readl(S3C2410_SRCPND),
+	    __raw_readl(S3C2410_EINTPEND));
+
+	s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
+				    s3c_irqwake_intmask);
+
+	s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
+				    s3c_irqwake_eintmask);
+
+	DBG("post sleep, preparing to return\n");
+
+	s3c2410_pm_check_restore();
+
+	/* ok, let's return from sleep */
+
+	DBG("S3C2410 PM Resume (post-restore)\n");
+	return 0;
+}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int s3c2410_pm_prepare(suspend_state_t state)
+{
+	return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static int s3c2410_pm_finish(suspend_state_t state)
+{
+	return 0;
+}
+
+/*
+ * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
+ */
+static struct pm_ops s3c2410_pm_ops = {
+	.pm_disk_mode	= PM_DISK_FIRMWARE,
+	.prepare	= s3c2410_pm_prepare,
+	.enter		= s3c2410_pm_enter,
+	.finish		= s3c2410_pm_finish,
+};
+
+/* s3c2410_pm_init
+ *
+ * Attach the power management functions. This should be called
+ * from the board specific initialisation if the board supports
+ * it.
+*/
+
+int __init s3c2410_pm_init(void)
+{
+	printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n");
+
+	pm_set_ops(&s3c2410_pm_ops);
+	return 0;
+}
diff --git a/arch/arm/mach-s3c2410/s3c244x-irq.c b/arch/arm/plat-s3c24xx/s3c244x-irq.c
similarity index 95%
rename from arch/arm/mach-s3c2410/s3c244x-irq.c
rename to arch/arm/plat-s3c24xx/s3c244x-irq.c
index ede9463..a0e39d8 100644
--- a/arch/arm/mach-s3c2410/s3c244x-irq.c
+++ b/arch/arm/plat-s3c24xx/s3c244x-irq.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c244x-irq.c
+/* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c
  *
  * Copyright (c) 2003,2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -35,9 +35,9 @@
 #include <asm/arch/regs-irq.h>
 #include <asm/arch/regs-gpio.h>
 
-#include "cpu.h"
-#include "pm.h"
-#include "irq.h"
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+#include <asm/plat-s3c24xx/irq.h>
 
 /* camera irq */
 
diff --git a/arch/arm/mach-s3c2410/s3c244x.c b/arch/arm/plat-s3c24xx/s3c244x.c
similarity index 92%
rename from arch/arm/mach-s3c2410/s3c244x.c
rename to arch/arm/plat-s3c24xx/s3c244x.c
index 23c7494..767f2e9 100644
--- a/arch/arm/mach-s3c2410/s3c244x.c
+++ b/arch/arm/plat-s3c24xx/s3c244x.c
@@ -1,9 +1,9 @@
-/* linux/arch/arm/mach-s3c2410/s3c244x.c
+/* linux/arch/arm/plat-s3c24xx/s3c244x.c
  *
  * Copyright (c) 2004-2006 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
- * Samsung S3C2440 and S3C2442 Mobile CPU support
+ * Samsung S3C2440 and S3C2442 Mobile CPU support (not S3C2443)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -35,13 +35,13 @@
 #include <asm/arch/regs-gpioj.h>
 #include <asm/arch/regs-dsc.h>
 
-#include "s3c2410.h"
-#include "s3c2440.h"
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/s3c2440.h>
 #include "s3c244x.h"
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
-#include "pm.h"
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
 
 static struct map_desc s3c244x_iodesc[] __initdata = {
 	IODESC_ENT(CLKPWR),
diff --git a/arch/arm/mach-s3c2410/s3c244x.h b/arch/arm/plat-s3c24xx/s3c244x.h
similarity index 93%
rename from arch/arm/mach-s3c2410/s3c244x.h
rename to arch/arm/plat-s3c24xx/s3c244x.h
index 1488c1e..f8ed176 100644
--- a/arch/arm/mach-s3c2410/s3c244x.h
+++ b/arch/arm/plat-s3c24xx/s3c244x.h
@@ -1,4 +1,4 @@
-/* arch/arm/mach-s3c2410/s3c244x.h
+/* linux/arch/arm/plat-s3c24xx/s3c244x.h
  *
  * Copyright (c) 2004-2005 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S
new file mode 100644
index 0000000..435349d
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/sleep.S
@@ -0,0 +1,157 @@
+/* linux/arch/arm/mach-s3c2410/sleep.S
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 Power Manager (Suspend-To-RAM) support
+ *
+ * Based on PXA/SA1100 sleep code by:
+ *	Nicolas Pitre, (c) 2002 Monta Vista Software Inc
+ *	Cliff Brake, (c) 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+#include <asm/arch/map.h>
+
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-serial.h>
+
+/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
+ * reset the UART configuration, only enable if you really need this!
+*/
+//#define CONFIG_DEBUG_RESUME
+
+	.text
+
+	/* s3c2410_cpu_save
+	 *
+	 * save enough of the CPU state to allow us to re-start
+	 * pm.c code. as we store items like the sp/lr, we will
+	 * end up returning from this function when the cpu resumes
+	 * so the return value is set to mark this.
+	 *
+	 * This arangement means we avoid having to flush the cache
+	 * from this code.
+	 *
+	 * entry:
+	 *	r0 = pointer to save block
+	 *
+	 * exit:
+	 *	r0 = 0 => we stored everything
+	 *	     1 => resumed from sleep
+	*/
+
+ENTRY(s3c2410_cpu_save)
+	stmfd	sp!, { r4 - r12, lr }
+
+	@@ store co-processor registers
+
+	mrc	p15, 0, r4, c13, c0, 0	@ PID
+	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID
+	mrc	p15, 0, r6, c2, c0, 0	@ translation table base address
+	mrc	p15, 0, r7, c1, c0, 0	@ control register
+
+	stmia	r0, { r4 - r13 }
+
+	mov	r0, #0
+	ldmfd	sp, { r4 - r12, pc }
+
+	@@ return to the caller, after having the MMU
+	@@ turned on, this restores the last bits from the
+	@@ stack
+resume_with_mmu:
+	mov	r0, #1
+	ldmfd	sp!, { r4 - r12, pc }
+
+	.ltorg
+
+	@@ the next bits sit in the .data segment, even though they
+	@@ happen to be code... the s3c2410_sleep_save_phys needs to be
+	@@ accessed by the resume code before it can restore the MMU.
+	@@ This means that the variable has to be close enough for the
+	@@ code to read it... since the .text segment needs to be RO,
+	@@ the data segment can be the only place to put this code.
+
+	.data
+
+	.global	s3c2410_sleep_save_phys
+s3c2410_sleep_save_phys:
+	.word	0
+
+	/* s3c2410_cpu_resume
+	 *
+	 * resume code entry for bootloader to call
+	 *
+	 * we must put this code here in the data segment as we have no
+	 * other way of restoring the stack pointer after sleep, and we
+	 * must not write to the code segment (code is read-only)
+	*/
+
+ENTRY(s3c2410_cpu_resume)
+	mov	r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+	msr	cpsr_c, r0
+
+	@@ load UART to allow us to print the two characters for
+	@@ resume debug
+
+	mov	r2, #S3C24XX_PA_UART & 0xff000000
+	orr	r2, r2, #S3C24XX_PA_UART & 0xff000
+
+#if 0
+	/* SMDK2440 LED set */
+	mov	r14, #S3C24XX_PA_GPIO
+	ldr	r12, [ r14, #0x54 ]
+	bic	r12, r12, #3<<4
+	orr	r12, r12, #1<<7
+	str	r12, [ r14, #0x54 ]
+#endif
+
+#ifdef CONFIG_DEBUG_RESUME
+	mov	r3, #'L'
+	strb	r3, [ r2, #S3C2410_UTXH ]
+1001:
+	ldrb	r14, [ r3, #S3C2410_UTRSTAT ]
+	tst	r14, #S3C2410_UTRSTAT_TXE
+	beq	1001b
+#endif /* CONFIG_DEBUG_RESUME */
+
+	mov	r1, #0
+	mcr	p15, 0, r1, c8, c7, 0		@@ invalidate I & D TLBs
+	mcr	p15, 0, r1, c7, c7, 0		@@ invalidate I & D caches
+
+	ldr	r0, s3c2410_sleep_save_phys	@ address of restore block
+	ldmia	r0, { r4 - r13 }
+
+	mcr	p15, 0, r4, c13, c0, 0		@ PID
+	mcr	p15, 0, r5, c3, c0, 0		@ Domain ID
+	mcr	p15, 0, r6, c2, c0, 0		@ translation table base
+
+#ifdef CONFIG_DEBUG_RESUME
+	mov	r3, #'R'
+	strb	r3, [ r2, #S3C2410_UTXH ]
+#endif
+
+	ldr	r2, =resume_with_mmu
+	mcr	p15, 0, r7, c1, c0, 0		@ turn on MMU, etc
+	nop					@ second-to-last before mmu
+	mov	pc, r2				@ go back to virtual address
+
+	.ltorg
diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/plat-s3c24xx/time.c
similarity index 98%
rename from arch/arm/mach-s3c2410/time.c
rename to arch/arm/plat-s3c24xx/time.c
index 9910bf0..c523d1c 100644
--- a/arch/arm/mach-s3c2410/time.c
+++ b/arch/arm/plat-s3c24xx/time.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/time.c
+/* linux/arch/arm/plat-s3c24xx/time.c
  *
  * Copyright (C) 2003-2005 Simtec Electronics
  *	Ben Dooks, <ben@simtec.co.uk>
@@ -37,8 +37,8 @@
 #include <asm/arch/regs-irq.h>
 #include <asm/mach/time.h>
 
-#include "clock.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 static unsigned long timer_startval;
 static unsigned long timer_usec_ticks;
diff --git a/arch/avr32/mach-at32ap/clock.c b/arch/avr32/mach-at32ap/clock.c
index 49e7b12..00c4354 100644
--- a/arch/avr32/mach-at32ap/clock.c
+++ b/arch/avr32/mach-at32ap/clock.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Atmel Corporation
  *
- * Based on arch/arm/mach-at91rm9200/clock.c
+ * Based on arch/arm/mach-at91/clock.c
  *   Copyright (C) 2005 David Brownell
  *   Copyright (C) 2005 Ivan Kokshaysky
  *
diff --git a/arch/avr32/mach-at32ap/clock.h b/arch/avr32/mach-at32ap/clock.h
index f953f04..bb8e1f2 100644
--- a/arch/avr32/mach-at32ap/clock.h
+++ b/arch/avr32/mach-at32ap/clock.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Atmel Corporation
  *
- * Based on arch/arm/mach-at91rm9200/clock.c
+ * Based on arch/arm/mach-at91/clock.c
  *   Copyright (C) 2005 David Brownell
  *   Copyright (C) 2005 Ivan Kokshaysky
  *
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c
index 107796e..d47cfbf 100644
--- a/arch/cris/arch-v10/drivers/pcf8563.c
+++ b/arch/cris/arch-v10/drivers/pcf8563.c
@@ -311,7 +311,7 @@
 {
 	pcf8563_init();
 	if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
-		printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n",
+		printk(KERN_INFO "%s: Unable to get major number %d for RTC device.\n",
 		       PCF8563_NAME, PCF8563_MAJOR);
 		return -1;
 	}
diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c
index 544ab01..24b919b 100644
--- a/arch/cris/arch-v32/drivers/pcf8563.c
+++ b/arch/cris/arch-v32/drivers/pcf8563.c
@@ -171,7 +171,7 @@
 		goto err;
 
 	if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
-		printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n",
+		printk(KERN_INFO "%s: Unable to get major number %d for RTC device.\n",
 		       PCF8563_NAME, PCF8563_MAJOR);
 		return -1;
 	}
diff --git a/arch/h8300/kernel/ints.c b/arch/h8300/kernel/ints.c
index 587ef7f..3e4f479 100644
--- a/arch/h8300/kernel/ints.c
+++ b/arch/h8300/kernel/ints.c
@@ -19,6 +19,7 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/seq_file.h>
+#include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/random.h>
 #include <linux/bootmem.h>
diff --git a/arch/h8300/platform/h8s/ints.c b/arch/h8300/platform/h8s/ints.c
index 567f681..a71d6e2 100644
--- a/arch/h8300/platform/h8s/ints.c
+++ b/arch/h8300/platform/h8s/ints.c
@@ -20,6 +20,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/bootmem.h>
 #include <linux/random.h>
 #include <linux/hardirq.h>
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 1df4a1f..2f76725 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -29,6 +29,7 @@
 config GENERIC_CLOCKEVENTS_BROADCAST
 	bool
 	default y
+	depends on X86_LOCAL_APIC
 
 config LOCKDEP_SUPPORT
 	bool
diff --git a/arch/i386/boot/compressed/relocs.c b/arch/i386/boot/compressed/relocs.c
index 881951c..ce4fda2 100644
--- a/arch/i386/boot/compressed/relocs.c
+++ b/arch/i386/boot/compressed/relocs.c
@@ -11,6 +11,7 @@
 #include <endian.h>
 
 #define MAX_SHDRS 100
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 static Elf32_Ehdr ehdr;
 static Elf32_Shdr shdr[MAX_SHDRS];
 static Elf32_Sym  *symtab[MAX_SHDRS];
@@ -71,7 +72,7 @@
 #undef SYM_TYPE
 	};
 	const char *name = "unknown sym type name";
-	if (type < sizeof(type_name)/sizeof(type_name[0])) {
+	if (type < ARRAY_SIZE(type_name)) {
 		name = type_name[type];
 	}
 	return name;
@@ -87,7 +88,7 @@
 #undef SYM_BIND
 	};
 	const char *name = "unknown sym bind name";
-	if (bind < sizeof(bind_name)/sizeof(bind_name[0])) {
+	if (bind < ARRAY_SIZE(bind_name)) {
 		name = bind_name[bind];
 	}
 	return name;
@@ -104,7 +105,7 @@
 #undef SYM_VISIBILITY
 	};
 	const char *name = "unknown sym visibility name";
-	if (visibility < sizeof(visibility_name)/sizeof(visibility_name[0])) {
+	if (visibility < ARRAY_SIZE(visibility_name)) {
 		name = visibility_name[visibility];
 	}
 	return name;
@@ -128,7 +129,7 @@
 #undef REL_TYPE
 	};
 	const char *name = "unknown type rel type name";
-	if (type < sizeof(type_name)/sizeof(type_name[0])) {
+	if (type < ARRAY_SIZE(type_name)) {
 		name = type_name[type];
 	}
 	return name;
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index fb3e723..e5eb97a 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -850,10 +850,9 @@
 static void __init acpi_process_madt(void)
 {
 #ifdef CONFIG_X86_LOCAL_APIC
-	int count, error;
+	int error;
 
-	count = acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt);
-	if (count >= 1) {
+	if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
 
 		/*
 		 * Parse MADT LAPIC entries
diff --git a/arch/i386/kernel/topology.c b/arch/i386/kernel/topology.c
index 79cf608..4578235 100644
--- a/arch/i386/kernel/topology.c
+++ b/arch/i386/kernel/topology.c
@@ -1,5 +1,5 @@
 /*
- * arch/i386/kernel/topology.c - Populate driverfs with topology information
+ * arch/i386/kernel/topology.c - Populate sysfs with topology information
  *
  * Written by: Matthew Dobson, IBM Corporation
  * Original Code: Paul Dorwin, IBM Corporation, Patrick Mochel, OSDL
diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
index 3700eef..8fda7be 100644
--- a/arch/i386/oprofile/nmi_int.c
+++ b/arch/i386/oprofile/nmi_int.c
@@ -63,7 +63,7 @@
 };
 
 
-static int __init init_driverfs(void)
+static int __init init_sysfs(void)
 {
 	int error;
 	if (!(error = sysdev_class_register(&oprofile_sysclass)))
@@ -72,15 +72,15 @@
 }
 
 
-static void exit_driverfs(void)
+static void exit_sysfs(void)
 {
 	sysdev_unregister(&device_oprofile);
 	sysdev_class_unregister(&oprofile_sysclass);
 }
 
 #else
-#define init_driverfs() do { } while (0)
-#define exit_driverfs() do { } while (0)
+#define init_sysfs() do { } while (0)
+#define exit_sysfs() do { } while (0)
 #endif /* CONFIG_PM */
 
 static int profile_exceptions_notify(struct notifier_block *self,
@@ -385,7 +385,7 @@
 	return 1;
 }
 
-/* in order to get driverfs right */
+/* in order to get sysfs right */
 static int using_nmi;
 
 int __init op_nmi_init(struct oprofile_operations *ops)
@@ -440,7 +440,7 @@
 			return -ENODEV;
 	}
 
-	init_driverfs();
+	init_sysfs();
 	using_nmi = 1;
 	ops->create_files = nmi_create_files;
 	ops->setup = nmi_setup;
@@ -456,5 +456,5 @@
 void op_nmi_exit(void)
 {
 	if (using_nmi)
-		exit_driverfs();
+		exit_sysfs();
 }
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c
index 53ca6e8..1bb0693 100644
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -191,6 +191,94 @@
 			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"),
 		},
 	},
+	{
+		.callback = set_bf_sort,
+		.ident = "HP ProLiant BL20p G3",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G3"),
+		},
+	},
+	{
+		.callback = set_bf_sort,
+		.ident = "HP ProLiant BL20p G4",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G4"),
+		},
+	},
+	{
+		.callback = set_bf_sort,
+		.ident = "HP ProLiant BL30p G1",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL30p G1"),
+		},
+	},
+	{
+		.callback = set_bf_sort,
+		.ident = "HP ProLiant BL25p G1",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL25p G1"),
+		},
+	},
+	{
+		.callback = set_bf_sort,
+		.ident = "HP ProLiant BL35p G1",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL35p G1"),
+		},
+	},
+	{
+		.callback = set_bf_sort,
+		.ident = "HP ProLiant BL45p G1",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G1"),
+		},
+	},
+	{
+		.callback = set_bf_sort,
+		.ident = "HP ProLiant BL45p G2",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G2"),
+		},
+	},
+	{
+		.callback = set_bf_sort,
+		.ident = "HP ProLiant BL460c G1",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL460c G1"),
+		},
+	},
+	{
+		.callback = set_bf_sort,
+		.ident = "HP ProLiant BL465c G1",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL465c G1"),
+		},
+	},
+	{
+		.callback = set_bf_sort,
+		.ident = "HP ProLiant BL480c G1",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL480c G1"),
+		},
+	},
+	{
+		.callback = set_bf_sort,
+		.ident = "HP ProLiant BL685c G1",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"),
+		},
+	},
 	{}
 };
 
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 9197d7b..3549c94 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -651,7 +651,7 @@
 	 * information -- the successor to MPS tables.
 	 */
 
-	if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt) < 1) {
+	if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
 		printk(KERN_ERR PREFIX "Can't find MADT\n");
 		goto skip_madt;
 	}
@@ -702,7 +702,7 @@
 	 * gets interrupts such as power and sleep buttons.  If it's not
 	 * on a Legacy interrupt, it needs to be setup.
 	 */
-	if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt) < 1)
+	if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt))
 		printk(KERN_ERR PREFIX "Can't find FADT\n");
 
 #ifdef CONFIG_SMP
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 2ecb20b..9ddf896 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -147,7 +147,7 @@
  * in UP:
  * 	- we need to protect against PMU overflow interrupts (local_irq_disable)
  *
- * spin_lock_irqsave()/spin_lock_irqrestore():
+ * spin_lock_irqsave()/spin_unlock_irqrestore():
  * 	in SMP: local_irq_disable + spin_lock
  * 	in UP : local_irq_disable
  *
diff --git a/arch/m32r/lib/usercopy.c b/arch/m32r/lib/usercopy.c
index 896cef1..82abd15 100644
--- a/arch/m32r/lib/usercopy.c
+++ b/arch/m32r/lib/usercopy.c
@@ -293,7 +293,7 @@
 		: "0" (n), "1" (s), "r" (n & 3), "r" (mask), "r"(0x01010101)
 		: "r0", "r1", "cbit");
 
-	/* NOTE: strnlen_user() algorism:
+	/* NOTE: strnlen_user() algorithm:
 	 * {
 	 *   char *p;
 	 *   for (p = s; n-- && *p != '\0'; ++p)
@@ -369,7 +369,7 @@
 		: "0" (n), "1" (s), "r" (n & 3), "r" (mask), "r"(0x01010101)
 		: "r0", "r1", "r2", "r3", "cbit");
 
-	/* NOTE: strnlen_user() algorism:
+	/* NOTE: strnlen_user() algorithm:
 	 * {
 	 *   char *p;
 	 *   for (p = s; n-- && *p != '\0'; ++p)
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
index 84aceca..b66c97c 100644
--- a/arch/m68k/kernel/ints.c
+++ b/arch/m68k/kernel/ints.c
@@ -28,6 +28,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/sched.h>
+#include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/errno.h>
 #include <linux/init.h>
diff --git a/arch/m68knommu/platform/5307/ints.c b/arch/m68knommu/platform/5307/ints.c
index a57239e..20f12a1 100644
--- a/arch/m68knommu/platform/5307/ints.c
+++ b/arch/m68knommu/platform/5307/ints.c
@@ -19,6 +19,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/errno.h>
 #include <linux/seq_file.h>
diff --git a/arch/m68knommu/platform/5307/timers.c b/arch/m68knommu/platform/5307/timers.c
index 87b112b..92e5807 100644
--- a/arch/m68knommu/platform/5307/timers.c
+++ b/arch/m68knommu/platform/5307/timers.c
@@ -104,7 +104,7 @@
 
 /*
  *	Choose a reasonably fast profile timer. Make it an odd value to
- *	try and get good coverage of kernal operations.
+ *	try and get good coverage of kernel operations.
  */
 #define	PROFILEHZ	1013
 
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index a92ce6b..c6f74f1 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -144,6 +144,7 @@
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
 	help
 	  The eXcite is a smart camera platform manufactured by
 	  Basler Vision Technologies AG
@@ -210,6 +211,7 @@
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
 	help
 	  This is an evaluation board based on the Galileo GT-64120
 	  single-chip system controller that contains a MIPS R5000 compatible
@@ -374,6 +376,7 @@
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
 	help
 	  The Jaguar ATX is a MIPS-based Single Board Computer (SBC) made by
 	  Momentum Computer <http://www.momenco.com/>.
@@ -391,6 +394,7 @@
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
 	help
 	  The Ocelot is a MIPS-based Single Board Computer (SBC) made by
 	  Momentum Computer <http://www.momenco.com/>.
@@ -480,6 +484,8 @@
 	select SYS_HAS_CPU_R5432
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+	select SYS_SUPPORTS_KGDB
+	select SYS_SUPPORTS_KGDB
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	help
 	  This enables support for the R5432-based NEC DDB Vrc-5477,
@@ -508,6 +514,7 @@
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select SYS_SUPPORTS_HIGHMEM
+	select SYS_SUPPORTS_KGDB
 	select SYS_SUPPORTS_SMP
 	help
 	  Yosemite is an evaluation board for the RM9000x2 processor
@@ -584,6 +591,7 @@
 	select SYS_HAS_CPU_R10000
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
 	select SYS_SUPPORTS_NUMA
 	select SYS_SUPPORTS_SMP
 	select GENERIC_HARDIRQS_NO__DO_IRQ
@@ -633,6 +641,7 @@
 	select SYS_HAS_CPU_SB1
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select SYS_SUPPORTS_HIGHMEM
+	select SYS_SUPPORTS_KGDB
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config SIBYTE_SENTOSA
@@ -726,15 +735,16 @@
 	select BOOT_ELF32
 	select DMA_NONCOHERENT
 	select GENERIC_ISA_DMA
-	select HAVE_STD_PC_SERIAL_PORT
 	select HW_HAS_EISA
 	select HW_HAS_PCI
+	select IRQ_CPU
 	select I8253
 	select I8259
 	select ISA
 	select SWAP_IO_SPACE if CPU_BIG_ENDIAN
 	select SYS_HAS_CPU_R4X00
 	select SYS_HAS_CPU_R5000
+	select SYS_HAS_CPU_R10000
 	select R5000_CPU_SCACHE
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
@@ -772,6 +782,7 @@
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
 	select TOSHIBA_BOARDS
 	select GENERIC_HARDIRQS_NO__DO_IRQ
 	help
@@ -792,6 +803,7 @@
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
 	select TOSHIBA_BOARDS
 	select GENERIC_HARDIRQS_NO__DO_IRQ
 	help
@@ -958,6 +970,7 @@
 
 config DDB5XXX_COMMON
 	bool
+	select SYS_SUPPORTS_KGDB
 
 config MIPS_BOARDS_GEN
 	bool
@@ -1006,6 +1019,7 @@
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_APM_EMULATION
+	select SYS_SUPPORTS_KGDB
 
 config PNX8550
 	bool
@@ -1018,6 +1032,7 @@
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select GENERIC_HARDIRQS_NO__DO_IRQ
+	select SYS_SUPPORTS_KGDB
 
 config SWAP_IO_SPACE
 	bool
@@ -1066,7 +1081,7 @@
 
 config MIPS_L1_CACHE_SHIFT
 	int
-	default "4" if MACH_DECSTATION
+	default "4" if MACH_DECSTATION || SNI_RM
 	default "7" if SGI_IP27
 	default "5"
 
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug
index 9351f1c..d5e60a0 100644
--- a/arch/mips/Kconfig.debug
+++ b/arch/mips/Kconfig.debug
@@ -39,7 +39,7 @@
 
 config KGDB
 	bool "Remote GDB kernel debugging"
-	depends on DEBUG_KERNEL
+	depends on DEBUG_KERNEL && SYS_SUPPORTS_KGDB
 	select DEBUG_INFO
 	help
 	  If you say Y here, it will be possible to remotely debug the MIPS
@@ -48,6 +48,9 @@
 	  better 32 MB RAM to avoid excessive linking time. This is only
 	  useful for kernel hackers. If unsure, say N.
 
+config SYS_SUPPORTS_KGDB
+	bool
+
 config GDB_CONSOLE
 	bool "Console output to GDB"
 	depends on KGDB
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
index a4b69b5..415ff87 100644
--- a/arch/mips/cobalt/setup.c
+++ b/arch/mips/cobalt/setup.c
@@ -130,7 +130,7 @@
 
 	set_io_port_base(CKSEG1ADDR(GT_DEF_PCI0_IO_BASE));
 
-	/* I/O port resource must include UART and LCD/buttons */
+	/* I/O port resource must include LCD/buttons */
 	ioport_resource.end = 0x0fffffff;
 
 	/* request I/O space for devices used on all i[345]86 PCs */
@@ -149,24 +149,24 @@
 	register_pci_controller(&cobalt_pci_controller);
 #endif
 
-#ifdef CONFIG_SERIAL_8250
 	if (cobalt_board_id > COBALT_BRD_ID_RAQ1) {
-
 #ifdef CONFIG_EARLY_PRINTK
 		cobalt_early_console();
 #endif
 
+#ifdef CONFIG_SERIAL_8250
 		uart.line	= 0;
 		uart.type	= PORT_UNKNOWN;
 		uart.uartclk	= 18432000;
 		uart.irq	= COBALT_SERIAL_IRQ;
-		uart.flags	= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
-		uart.iobase	= 0xc800000;
-		uart.iotype	= UPIO_PORT;
+		uart.flags	= UPF_IOREMAP | UPF_BOOT_AUTOCONF |
+				  UPF_SKIP_TEST;
+		uart.iotype	= UPIO_MEM;
+		uart.mapbase	= 0x1c800000;
 
 		early_serial_setup(&uart);
-	}
 #endif
+	}
 }
 
 /*
diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
index ac18916..45874d1 100644
--- a/arch/mips/configs/atlas_defconfig
+++ b/arch/mips/configs/atlas_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 09:59:39 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:35 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 CONFIG_MIPS_ATLAS=y
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,10 +64,14 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_MIPS_BONITO64=y
@@ -129,8 +133,8 @@
 CONFIG_RM7000_CPU_SCACHE=y
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_SYS_SUPPORTS_MULTITHREADING=y
 # CONFIG_64BIT_PHYS_ADDR is not set
@@ -149,6 +153,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 CONFIG_HZ_100=y
 # CONFIG_HZ_128 is not set
@@ -161,6 +166,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -179,15 +185,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -195,12 +206,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -218,6 +229,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -260,6 +272,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -273,7 +293,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
@@ -281,7 +304,6 @@
 # CONFIG_IP_FIB_TRIE is not set
 CONFIG_IP_FIB_HASH=y
 CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_FWMARK=y
 CONFIG_IP_ROUTE_MULTIPATH=y
 # CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
 CONFIG_IP_ROUTE_VERBOSE=y
@@ -304,10 +326,13 @@
 CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -349,11 +374,17 @@
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=y
 CONFIG_INET6_XFRM_TUNNEL=m
 CONFIG_INET6_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_TRANSPORT=m
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
 CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -365,19 +396,43 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
 CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
@@ -395,60 +450,45 @@
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_CT_ACCT=y
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CONNTRACK_SECMARK=y
-CONFIG_IP_NF_CONNTRACK_EVENTS=y
-CONFIG_IP_NF_CONNTRACK_NETLINK=m
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_PPTP=m
-CONFIG_IP_NF_H323=m
-CONFIG_IP_NF_SIP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_MATCH_OWNER=m
 CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_NAT_PPTP=m
-CONFIG_IP_NF_NAT_H323=m
-CONFIG_IP_NF_NAT_SIP=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
 CONFIG_IP_NF_TARGET_TTL=m
 # CONFIG_IP_NF_TARGET_CLUSTERIP is not set
 CONFIG_IP_NF_RAW=m
@@ -459,6 +499,7 @@
 #
 # IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
+CONFIG_NF_CONNTRACK_IPV6=m
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_RT=m
@@ -468,6 +509,7 @@
 CONFIG_IP6_NF_MATCH_OWNER=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_MH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
@@ -527,13 +569,12 @@
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 CONFIG_ATALK=m
-CONFIG_DEV_APPLETALK=y
+CONFIG_DEV_APPLETALK=m
 CONFIG_IPDDP=m
 CONFIG_IPDDP_ENCAP=y
 CONFIG_IPDDP_DECAP=y
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-CONFIG_NET_DIVERT=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -541,6 +582,7 @@
 # QoS and/or fair queueing
 #
 CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FIFO=y
 CONFIG_NET_SCH_CLK_JIFFIES=y
 # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
 # CONFIG_NET_SCH_CLK_CPU is not set
@@ -595,6 +637,7 @@
 CONFIG_IEEE80211_SOFTMAC=m
 # CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
 CONFIG_WIRELESS_EXT=y
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -642,6 +685,7 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -649,9 +693,16 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -681,6 +732,8 @@
 #
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -700,14 +753,17 @@
 CONFIG_SCSI_MULTI_LUN=y
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SAS_LIBSAS_DEBUG=y
 
 #
 # SCSI low-level drivers
@@ -720,30 +776,39 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+CONFIG_SCSI_AIC94XX=m
+# CONFIG_AIC94XX_DEBUG is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 CONFIG_SCSI_SYM53C8XX_MMIO=y
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -759,6 +824,7 @@
 CONFIG_MD_MULTIPATH=m
 CONFIG_MD_FAULTY=m
 CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
@@ -813,6 +879,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -832,6 +900,7 @@
 # CONFIG_HP100 is not set
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=y
+# CONFIG_PCNET32_NAPI is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
@@ -850,6 +919,7 @@
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 CONFIG_LAN_SAA9730=y
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -868,14 +938,18 @@
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -915,6 +989,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -995,10 +1070,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -1006,7 +1077,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -1031,14 +1101,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -1056,6 +1121,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -1063,6 +1129,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -1125,6 +1197,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1134,6 +1214,7 @@
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1154,6 +1235,7 @@
 CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=m
 CONFIG_ROMFS_FS=m
@@ -1167,6 +1249,7 @@
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -1174,7 +1257,6 @@
 CONFIG_ISO9660_FS=m
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
-CONFIG_ZISOFS_FS=m
 CONFIG_UDF_FS=m
 CONFIG_UDF_NLS=y
 
@@ -1193,11 +1275,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -1242,7 +1326,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1299,6 +1382,14 @@
 CONFIG_NLS_UTF8=m
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1308,11 +1399,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1326,18 +1419,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1349,6 +1454,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1358,6 +1464,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1369,9 +1476,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
-CONFIG_RIO=n
-CONFIG_I2C_OCORES=n
-CONFIG_DEBUG_RT_MUTEXES=n
-CONFIG_RT_MUTEX_TESTER=n
-CONFIG_DEBUG_RWSEMS=n
-CONFIG_DEBUG_LOCKING_API_SELFTESTS=n
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index 9554257..b4cdd3e 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc1
-# Wed Oct 11 01:41:41 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:35 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -40,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -78,11 +80,14 @@
 # CONFIG_SIBYTE_SB1250_PROF is not set
 # CONFIG_SIBYTE_TBPROF is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_COHERENT=y
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -115,6 +120,7 @@
 # CONFIG_CPU_RM9000 is not set
 CONFIG_CPU_SB1=y
 CONFIG_SYS_HAS_CPU_SB1=y
+CONFIG_WEAK_ORDERING=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@@ -150,8 +156,10 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
 CONFIG_SMP=y
 CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_NR_CPUS_DEFAULT_4=y
 CONFIG_NR_CPUS=4
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
@@ -166,6 +174,7 @@
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_PREEMPT_BKL is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -185,6 +194,7 @@
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
@@ -193,6 +203,7 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_CPUSETS is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -253,7 +264,6 @@
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
-# CONFIG_PCI_MULTITHREAD_PROBE is not set
 CONFIG_PCI_DEBUG=y
 CONFIG_MMU=y
 
@@ -273,11 +283,20 @@
 # CONFIG_BUILD_ELF64 is not set
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
 CONFIG_MIPS32_O32=y
 CONFIG_MIPS32_N32=y
 CONFIG_BINFMT_ELF32=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -292,7 +311,9 @@
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 # CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -318,6 +339,7 @@
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -374,6 +396,7 @@
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -413,6 +436,12 @@
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
@@ -455,6 +484,7 @@
 # CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -464,6 +494,7 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_TC86C001=m
 # CONFIG_BLK_DEV_IDE_SWARM is not set
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
@@ -563,9 +594,11 @@
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -627,6 +660,7 @@
 # CONFIG_DIGIEPCA is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
+CONFIG_MOXA_SMARTIO_NEW=m
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_SYNCLINK_GT is not set
@@ -667,10 +701,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -678,7 +708,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -707,6 +736,7 @@
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PASEMI is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 CONFIG_I2C_SIBYTE=y
@@ -743,6 +773,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -751,11 +782,6 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-# CONFIG_TIFM_CORE is not set
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -840,6 +866,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -848,6 +882,7 @@
 CONFIG_EXT2_FS_SECURITY=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
@@ -889,7 +924,7 @@
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -946,6 +981,10 @@
 #
 # Distributed Lock Manager
 #
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
 
 #
 # Profiling support
@@ -960,23 +999,25 @@
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_RWSEMS is not set
 # CONFIG_DEBUG_LOCK_ALLOC is not set
 # CONFIG_PROVE_LOCKING is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
@@ -1002,8 +1043,9 @@
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=m
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
@@ -1012,9 +1054,13 @@
 CONFIG_CRYPTO_SHA512=y
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_TWOFISH_COMMON=y
@@ -1029,6 +1075,7 @@
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_MICHAEL_MIC=y
 # CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1038,6 +1085,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
@@ -1045,3 +1093,5 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
index 49590d4..b05469e 100644
--- a/arch/mips/configs/capcella_defconfig
+++ b/arch/mips/configs/capcella_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:03:24 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:36 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 CONFIG_MACH_VR41XX=y
 # CONFIG_PMC_YOSEMITE is not set
@@ -70,12 +70,15 @@
 # CONFIG_VICTOR_MPC30X is not set
 CONFIG_ZAO_CAPCELLA=y
 CONFIG_PCI_VR41XX=y
-# CONFIG_VRC4173 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
@@ -108,6 +111,7 @@
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_VR41XX=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
@@ -121,8 +125,8 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -137,6 +141,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -149,6 +154,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -167,15 +173,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -183,12 +194,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -206,6 +217,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -248,6 +260,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -261,7 +281,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -282,10 +305,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -315,7 +341,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -378,14 +403,22 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -414,6 +447,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -464,6 +503,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -504,7 +545,7 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_LAN_SAA9730 is not set
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -523,14 +564,18 @@
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -569,6 +614,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -635,10 +681,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 CONFIG_GPIO_VR41XX=y
 # CONFIG_RAW_DRIVER is not set
@@ -647,7 +689,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -672,14 +713,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -697,6 +733,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -704,6 +741,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -754,6 +796,7 @@
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
 CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
 
 #
 # RTC interfaces
@@ -787,16 +830,26 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -807,6 +860,7 @@
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -826,11 +880,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -868,7 +924,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -886,6 +941,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -895,11 +958,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="mem=32M console=ttyVR0,38400"
 
@@ -912,7 +977,44 @@
 #
 # Cryptographic options
 #
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CAMELLIA=m
+# CONFIG_CRYPTO_TEST is not set
 
 #
 # Hardware crypto devices
@@ -921,8 +1023,13 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index 0607fc2..1a3d776 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:03:25 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:37 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 CONFIG_MIPS_COBALT=y
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -65,10 +65,14 @@
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_EARLY_PRINTK=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_I8259=y
@@ -117,8 +121,8 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
@@ -134,6 +138,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -146,6 +151,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -164,15 +170,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -180,12 +191,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -198,6 +209,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -240,6 +252,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -253,7 +273,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -270,10 +293,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -303,7 +329,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -379,9 +404,16 @@
 CONFIG_ATA_OVER_ETH=y
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=y
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -417,8 +449,10 @@
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+CONFIG_BLK_DEV_IT8213=y
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -428,6 +462,7 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 CONFIG_BLK_DEV_VIA82CXXX=y
+CONFIG_BLK_DEV_TC86C001=y
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -439,6 +474,12 @@
 #
 CONFIG_RAID_ATTRS=y
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -489,6 +530,8 @@
 CONFIG_CICADA_PHY=y
 CONFIG_VITESSE_PHY=y
 CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -533,14 +576,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=y
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=y
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=y
 
 #
 # Token Ring devices
@@ -579,6 +625,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -656,10 +703,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -667,7 +710,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -692,14 +734,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -717,6 +754,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -724,6 +762,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -786,6 +829,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -794,11 +845,13 @@
 CONFIG_EXT2_FS_SECURITY=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -809,6 +862,7 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=y
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -828,17 +882,20 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=y
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -866,7 +923,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -884,6 +940,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=y
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -893,12 +957,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
-# CONFIG_UNWIND_INFO is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -913,7 +978,12 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
 CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
@@ -922,9 +992,16 @@
 CONFIG_CRYPTO_SHA512=y
 CONFIG_CRYPTO_WP512=y
 CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_LRW=y
 CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=y
 CONFIG_CRYPTO_BLOWFISH=y
 CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
 CONFIG_CRYPTO_SERPENT=y
 CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_CAST5=y
@@ -936,6 +1013,7 @@
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CAMELLIA=y
 
 #
 # Hardware crypto devices
@@ -944,6 +1022,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=y
 CONFIG_CRC32=y
@@ -951,3 +1030,5 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 1a57b33..1db19f1 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:03:33 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:39 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,14 +64,19 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 CONFIG_SOC_AU1000=y
 CONFIG_SOC_AU1X00=y
@@ -116,8 +121,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
 CONFIG_CPU_HAS_LLSC=y
@@ -135,6 +140,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -147,6 +153,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -165,15 +172,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -181,12 +193,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -204,6 +216,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -252,6 +265,10 @@
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
 # CONFIG_PM is not set
 
 #
@@ -268,7 +285,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -289,10 +309,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -311,15 +334,42 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
-# CONFIG_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
@@ -330,14 +380,17 @@
 CONFIG_NETFILTER_XT_MATCH_QUOTA=m
 CONFIG_NETFILTER_XT_MATCH_REALM=m
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -365,7 +418,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -421,11 +473,13 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -510,6 +564,10 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -519,6 +577,12 @@
 #
 CONFIG_RAID_ATTRS=m
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -562,6 +626,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -616,6 +682,7 @@
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -635,6 +702,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -714,10 +782,6 @@
 # CONFIG_R3964 is not set
 
 #
-# Ftape, the floppy tape device driver
-#
-
-#
 # PCMCIA character devices
 #
 CONFIG_SYNCLINK_CS=m
@@ -729,7 +793,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -754,14 +817,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -779,6 +837,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -786,6 +845,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -847,6 +911,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -858,6 +930,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -870,6 +943,7 @@
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -880,6 +954,7 @@
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -899,23 +974,25 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
@@ -944,7 +1021,6 @@
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1001,6 +1077,14 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1010,11 +1094,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1029,18 +1115,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1052,6 +1150,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1061,6 +1160,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1072,3 +1172,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index 0055ec4..529e6eb 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:03:34 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:39 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,14 +64,19 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 CONFIG_SOC_AU1100=y
 CONFIG_SOC_AU1X00=y
@@ -116,8 +121,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
 CONFIG_CPU_HAS_LLSC=y
@@ -135,6 +140,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -147,6 +153,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -165,15 +172,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -181,12 +193,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -204,6 +216,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -241,6 +254,10 @@
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
 # CONFIG_PM is not set
 
 #
@@ -257,7 +274,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -278,10 +298,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -300,15 +323,42 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
-# CONFIG_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
@@ -319,14 +369,17 @@
 CONFIG_NETFILTER_XT_MATCH_QUOTA=m
 CONFIG_NETFILTER_XT_MATCH_REALM=m
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -354,7 +407,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -410,11 +462,13 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -499,6 +553,10 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -508,6 +566,12 @@
 #
 CONFIG_RAID_ATTRS=m
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -551,6 +615,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -592,6 +658,7 @@
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -611,6 +678,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -687,17 +755,12 @@
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -722,14 +785,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -744,6 +802,7 @@
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
@@ -786,6 +845,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -847,6 +911,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -858,6 +930,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -870,6 +943,7 @@
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -880,6 +954,7 @@
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -899,23 +974,25 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
@@ -944,7 +1021,6 @@
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1001,6 +1077,14 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1010,11 +1094,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1029,18 +1115,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1052,6 +1150,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1061,6 +1160,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1072,3 +1172,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index c41823b..9e86dcd 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:03:43 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:40 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,14 +64,19 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_COHERENT=y
 CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 CONFIG_SOC_AU1200=y
 CONFIG_SOC_AU1X00=y
@@ -116,8 +121,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
 CONFIG_CPU_HAS_LLSC=y
@@ -135,6 +140,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -147,6 +153,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -165,16 +172,21 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -182,12 +194,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -205,6 +217,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -251,6 +264,10 @@
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
 # CONFIG_PM is not set
 
 #
@@ -267,7 +284,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -285,10 +305,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -305,15 +328,41 @@
 # Core Netfilter Configuration
 #
 # CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
@@ -324,14 +373,17 @@
 CONFIG_NETFILTER_XT_MATCH_QUOTA=m
 CONFIG_NETFILTER_XT_MATCH_REALM=m
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -359,7 +411,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -409,11 +460,13 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -499,14 +552,20 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -540,6 +599,8 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -559,20 +620,21 @@
 CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
 # CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
@@ -585,6 +647,11 @@
 # CONFIG_PCMCIA_SYM53C500 is not set
 
 #
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
@@ -672,6 +739,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -751,10 +819,6 @@
 # CONFIG_R3964 is not set
 
 #
-# Ftape, the floppy tape device driver
-#
-
-#
 # PCMCIA character devices
 #
 # CONFIG_SYNCLINK_CS is not set
@@ -766,7 +830,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -782,6 +845,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -790,14 +854,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -812,6 +871,7 @@
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
@@ -843,6 +903,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -916,6 +982,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -927,6 +1001,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -938,6 +1013,7 @@
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -948,6 +1024,7 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -955,7 +1032,6 @@
 CONFIG_ISO9660_FS=m
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
-CONFIG_ZISOFS_FS=m
 CONFIG_UDF_FS=m
 CONFIG_UDF_NLS=y
 
@@ -974,23 +1050,25 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
@@ -1025,7 +1103,6 @@
 CONFIG_SMB_FS=y
 # CONFIG_SMB_NLS_DEFAULT is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1082,6 +1159,14 @@
 CONFIG_NLS_UTF8=m
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1091,11 +1176,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="mem=48M"
 
@@ -1109,7 +1196,44 @@
 #
 # Cryptographic options
 #
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
+# CONFIG_CRYPTO_TEST is not set
 
 #
 # Hardware crypto devices
@@ -1118,6 +1242,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=y
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
@@ -1129,3 +1254,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index 7d6d921..9c94461 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:03:56 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:41 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,15 +64,20 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 CONFIG_SOC_AU1500=y
@@ -118,8 +123,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
 CONFIG_CPU_HAS_LLSC=y
@@ -136,7 +141,8 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -149,6 +155,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -167,15 +174,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -183,12 +195,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -206,6 +218,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -259,6 +272,10 @@
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
 # CONFIG_PM is not set
 
 #
@@ -275,7 +292,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -296,10 +316,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -318,15 +341,42 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
-# CONFIG_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
@@ -337,14 +387,17 @@
 CONFIG_NETFILTER_XT_MATCH_QUOTA=m
 CONFIG_NETFILTER_XT_MATCH_REALM=m
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -372,7 +425,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -428,11 +480,13 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -488,6 +542,7 @@
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
+# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -524,9 +579,16 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -536,6 +598,7 @@
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -556,6 +619,12 @@
 #
 CONFIG_RAID_ATTRS=m
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -606,6 +675,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -643,14 +714,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -683,6 +757,7 @@
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -702,6 +777,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -780,10 +856,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 
 #
@@ -798,7 +870,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -823,14 +894,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -843,6 +909,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -873,7 +940,6 @@
 # Generic devices
 #
 CONFIG_SND_AC97_CODEC=m
-CONFIG_SND_AC97_BUS=m
 # CONFIG_SND_DUMMY is not set
 CONFIG_SND_VIRMIDI=m
 CONFIG_SND_MTPAV=m
@@ -938,6 +1004,7 @@
 # CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
 # CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_AC97_POWER_SAVE is not set
 
 #
 # ALSA MIPS devices
@@ -956,18 +1023,28 @@
 # CONFIG_SND_PDAUDIOCF is not set
 
 #
+# SoC audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=y
+# CONFIG_OBSOLETE_OSS is not set
 # CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_ES1371 is not set
 # CONFIG_SOUND_ICH is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
 # CONFIG_SOUND_VIA82CXXX is not set
+CONFIG_AC97_BUS=m
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
 
 #
 # USB support
@@ -982,7 +1059,6 @@
 # Miscellaneous USB options
 #
 # CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
 
@@ -992,7 +1068,8 @@
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
@@ -1010,14 +1087,12 @@
 #
 # may also be needed; see USB_STORAGE Help for more information
 #
-# CONFIG_USB_STORAGE is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 # CONFIG_USB_HIDDEV is not set
@@ -1033,6 +1108,7 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -1046,6 +1122,7 @@
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 CONFIG_USB_MON=y
 
@@ -1063,18 +1140,20 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX 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_CY7C63 is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 CONFIG_USB_LD=m
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB DSL modem support
@@ -1131,6 +1210,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1142,6 +1229,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1154,6 +1242,7 @@
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1164,6 +1253,7 @@
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -1183,23 +1273,25 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
@@ -1228,7 +1320,6 @@
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1285,6 +1376,14 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1294,11 +1393,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1313,18 +1414,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1336,6 +1449,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1345,6 +1459,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1356,3 +1471,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index c681c91..5b18d5d 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:03:59 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:42 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,15 +64,20 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 CONFIG_SOC_AU1550=y
 CONFIG_SOC_AU1X00=y
@@ -117,8 +122,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
 CONFIG_CPU_HAS_LLSC=y
@@ -135,7 +140,8 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -148,6 +154,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -166,15 +173,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -182,12 +194,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -205,6 +217,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -258,6 +271,10 @@
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
 # CONFIG_PM is not set
 
 #
@@ -274,7 +291,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -295,10 +315,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -317,15 +340,42 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
-# CONFIG_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
@@ -336,14 +386,17 @@
 CONFIG_NETFILTER_XT_MATCH_QUOTA=m
 CONFIG_NETFILTER_XT_MATCH_REALM=m
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -371,7 +424,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -427,11 +479,13 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -492,6 +546,7 @@
 CONFIG_MTD_NAND_IDS=m
 CONFIG_MTD_NAND_AU1550=m
 # CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
 
 #
@@ -528,9 +583,16 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -540,6 +602,7 @@
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -567,8 +630,10 @@
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -578,6 +643,7 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_TC86C001=m
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -589,6 +655,12 @@
 #
 CONFIG_RAID_ATTRS=m
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -639,6 +711,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -676,14 +750,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -724,6 +801,7 @@
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -743,6 +821,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -821,10 +900,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 
 #
@@ -839,7 +914,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -864,14 +938,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -883,6 +952,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -890,6 +960,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -952,6 +1027,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -963,6 +1046,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -975,6 +1059,7 @@
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -985,6 +1070,7 @@
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -1004,23 +1090,25 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
@@ -1049,7 +1137,6 @@
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1106,6 +1193,14 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1115,11 +1210,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1134,18 +1231,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1157,6 +1266,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1166,6 +1276,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1177,3 +1288,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig
index dd4bb00..1210188 100644
--- a/arch/mips/configs/ddb5477_defconfig
+++ b/arch/mips/configs/ddb5477_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:00 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:43 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 CONFIG_DDB5477=y
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -65,10 +65,14 @@
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_DDB5477_BUS_FREQUENCY=0
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_I8259=y
@@ -117,8 +121,8 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
@@ -134,6 +138,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -146,6 +151,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -164,15 +170,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -180,12 +191,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -198,6 +209,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -240,6 +252,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -253,7 +273,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -273,10 +296,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -306,7 +332,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -381,6 +406,12 @@
 CONFIG_ATA_OVER_ETH=y
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=y
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -390,6 +421,12 @@
 #
 CONFIG_RAID_ATTRS=y
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -440,6 +477,8 @@
 CONFIG_CICADA_PHY=y
 CONFIG_VITESSE_PHY=y
 CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -459,6 +498,7 @@
 # CONFIG_HP100 is not set
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=y
+# CONFIG_PCNET32_NAPI is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
@@ -476,7 +516,7 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_LAN_SAA9730 is not set
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -495,14 +535,18 @@
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=y
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=y
 
 #
 # Token Ring devices
@@ -541,6 +585,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -618,10 +663,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -629,7 +670,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -654,14 +694,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -679,6 +714,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -686,6 +722,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -748,16 +789,26 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -787,17 +838,19 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=y
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -829,7 +882,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -847,6 +899,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=y
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -856,12 +916,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
-# CONFIG_UNWIND_INFO is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="ip=any"
 
@@ -876,7 +937,12 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
 CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
@@ -885,9 +951,16 @@
 CONFIG_CRYPTO_SHA512=y
 CONFIG_CRYPTO_WP512=y
 CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_LRW=y
 CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=y
 CONFIG_CRYPTO_BLOWFISH=y
 CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
 CONFIG_CRYPTO_SERPENT=y
 CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_CAST5=y
@@ -899,6 +972,7 @@
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CAMELLIA=y
 
 #
 # Hardware crypto devices
@@ -907,6 +981,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=y
 CONFIG_CRC32=y
@@ -914,3 +989,5 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 8a31ce4..2d71745 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Tue Oct  3 11:57:53 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:44 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 CONFIG_MACH_DECSTATION=y
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -65,10 +65,14 @@
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_EARLY_PRINTK=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
@@ -116,8 +120,8 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_WB=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -133,6 +137,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_128=y
@@ -147,6 +152,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -165,13 +171,16 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
@@ -246,6 +255,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -260,7 +277,9 @@
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=m
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -281,11 +300,13 @@
 CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 CONFIG_IPV6=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
@@ -298,10 +319,12 @@
 CONFIG_INET6_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_TRANSPORT=m
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
 CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
 # CONFIG_IPV6_TUNNEL is not set
-CONFIG_IPV6_SUBTREES=y
 CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
 CONFIG_NETWORK_SECMARK=y
 # CONFIG_NETFILTER is not set
 
@@ -389,6 +412,10 @@
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -398,6 +425,7 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
 # CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
@@ -418,6 +446,7 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
 # SCSI Transports
@@ -502,6 +531,9 @@
 # Wan interfaces
 #
 # CONFIG_WAN is not set
+CONFIG_FDDI=y
+CONFIG_DEFXX=m
+CONFIG_DEFXX_MMIO=y
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
@@ -565,17 +597,12 @@
 CONFIG_RTC=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -600,14 +627,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -622,6 +644,7 @@
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
@@ -709,6 +732,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -720,6 +751,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -727,6 +759,7 @@
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -737,6 +770,7 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -806,7 +840,6 @@
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
 # CONFIG_9P_FS is not set
-CONFIG_GENERIC_ACL=y
 
 #
 # Partition Types
@@ -835,6 +868,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -847,9 +888,10 @@
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -866,19 +908,24 @@
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=m
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_TWOFISH_COMMON=m
@@ -893,6 +940,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -902,6 +950,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
@@ -909,3 +958,5 @@
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
index 6fa4f91..0ee2fbb 100644
--- a/arch/mips/configs/e55_defconfig
+++ b/arch/mips/configs/e55_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc2
-# Tue Jul 25 23:15:03 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:44 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 CONFIG_MACH_VR41XX=y
 # CONFIG_PMC_YOSEMITE is not set
@@ -70,10 +70,14 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
@@ -106,6 +110,7 @@
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_VR41XX=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
@@ -119,8 +124,8 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -135,6 +140,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -147,6 +153,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -165,13 +172,17 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_UTS_NS is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 # CONFIG_HOTPLUG is not set
@@ -179,12 +190,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -202,6 +213,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -241,6 +253,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 # CONFIG_NET is not set
@@ -288,9 +308,14 @@
 # CONFIG_CDROM_PKTCDVD is not set
 
 #
+# Misc devices
+#
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -319,6 +344,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Old CD-ROM drivers (not SCSI, not IDE)
@@ -356,6 +387,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -436,10 +468,6 @@
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 CONFIG_GPIO_VR41XX=y
 # CONFIG_RAW_DRIVER is not set
 
@@ -447,7 +475,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -463,6 +490,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -471,14 +499,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -496,6 +519,7 @@
 # CONFIG_VGA_CONSOLE is not set
 # CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -503,6 +527,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
@@ -563,16 +593,26 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -582,6 +622,7 @@
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -601,8 +642,10 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
@@ -645,11 +688,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x1f0,0x3f6,40 mem=8M"
 
@@ -665,10 +710,6 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
@@ -676,3 +717,5 @@
 # CONFIG_CRC32 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig
index 4c9d040..218fe6e 100644
--- a/arch/mips/configs/emma2rh_defconfig
+++ b/arch/mips/configs/emma2rh_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:05 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:46 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,10 +64,14 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_CPU_BIG_ENDIAN=y
@@ -116,8 +120,8 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -134,6 +138,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -147,6 +152,7 @@
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_PREEMPT_BKL=y
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -166,17 +172,22 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -184,12 +195,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -207,6 +218,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 CONFIG_LBD=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -249,6 +261,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -262,7 +282,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
@@ -270,7 +293,6 @@
 # CONFIG_IP_FIB_TRIE is not set
 CONFIG_IP_FIB_HASH=y
 CONFIG_IP_MULTIPLE_TABLES=y
-# CONFIG_IP_ROUTE_FWMARK is not set
 CONFIG_IP_ROUTE_MULTIPATH=y
 # CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
 CONFIG_IP_ROUTE_VERBOSE=y
@@ -287,13 +309,16 @@
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -305,11 +330,17 @@
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 # CONFIG_INET6_IPCOMP is not set
+CONFIG_IPV6_MIP6=y
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
 CONFIG_INET6_XFRM_MODE_TRANSPORT=m
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
 # CONFIG_IPV6_TUNNEL is not set
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -318,19 +349,125 @@
 # Core Netfilter Configuration
 #
 # CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NF_CONNTRACK is not set
-# CONFIG_NETFILTER_XTABLES is not set
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
 
 #
 # IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
+CONFIG_NF_CONNTRACK_IPV6=m
 # CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_RAW=m
 
 #
 # DCCP Configuration (EXPERIMENTAL)
@@ -360,7 +497,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -368,6 +504,7 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -377,6 +514,7 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_IEEE80211 is not set
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -387,7 +525,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -409,11 +547,13 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -471,6 +611,7 @@
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
+# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -504,6 +645,12 @@
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -513,6 +660,8 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
+CONFIG_SCSI_TGT=m
+# CONFIG_SCSI_NETLINK is not set
 # CONFIG_SCSI_PROC_FS is not set
 
 #
@@ -531,14 +680,17 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
 
 #
 # SCSI low-level drivers
@@ -551,26 +703,35 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+CONFIG_SCSI_AIC94XX=m
+# CONFIG_AIC94XX_DEBUG is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -649,7 +810,7 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_LAN_SAA9730 is not set
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -668,14 +829,18 @@
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -703,6 +868,7 @@
 # CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
@@ -723,6 +889,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -790,10 +957,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -801,7 +964,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -830,6 +992,7 @@
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PASEMI is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_I2C_SIS5595 is not set
@@ -865,6 +1028,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -898,29 +1062,27 @@
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -932,6 +1094,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -939,6 +1102,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -1001,6 +1169,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1012,6 +1188,7 @@
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=m
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1023,6 +1200,7 @@
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1033,6 +1211,7 @@
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=m
 # CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -1057,11 +1236,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -1073,7 +1254,6 @@
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
@@ -1118,7 +1298,6 @@
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1175,6 +1354,14 @@
 CONFIG_NLS_UTF8=m
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1184,11 +1371,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="console=ttyS0,115200 mem=192m ip=bootp root=/dev/nfs rw"
 
@@ -1202,7 +1391,12 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
@@ -1211,7 +1405,13 @@
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=m
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -1225,6 +1425,7 @@
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1234,10 +1435,17 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
index d5b4973..5ad4870 100644
--- a/arch/mips/configs/ev64120_defconfig
+++ b/arch/mips/configs/ev64120_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:05 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:46 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 CONFIG_MIPS_EV64120=y
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -65,10 +65,14 @@
 # CONFIG_TOSHIBA_RBTX4938 is not set
 # CONFIG_EVB_PCI1 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_CPU_BIG_ENDIAN=y
@@ -118,8 +122,8 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -136,6 +140,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -148,6 +153,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -166,15 +172,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -182,12 +193,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -205,6 +216,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -247,6 +259,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -259,7 +279,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -279,10 +302,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -312,7 +338,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -386,6 +411,12 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -395,6 +426,12 @@
 #
 CONFIG_RAID_ATTRS=m
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -445,6 +482,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -480,14 +519,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -515,6 +557,7 @@
 CONFIG_PPP_MPPE=m
 # CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=y
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -534,6 +577,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -611,10 +655,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -622,7 +662,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -647,14 +686,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -672,6 +706,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -679,6 +714,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -741,16 +781,26 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -780,17 +830,19 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -819,7 +871,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -837,6 +888,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -846,11 +905,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal ip=192.168.1.211:192.168.1.1:::gt::"
 
@@ -865,18 +926,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -888,6 +961,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -897,6 +971,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=m
 CONFIG_CRC_CCITT=y
 CONFIG_CRC16=m
 CONFIG_CRC32=m
@@ -904,3 +979,5 @@
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig
index 697140c..5e179fe 100644
--- a/arch/mips/configs/excite_defconfig
+++ b/arch/mips/configs/excite_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:09 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:47 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -26,8 +27,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -43,6 +42,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -65,10 +65,14 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_COHERENT=y
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -76,6 +80,10 @@
 CONFIG_IRQ_CPU=y
 CONFIG_IRQ_CPU_RM7K=y
 CONFIG_IRQ_CPU_RM9K=y
+CONFIG_MIPS_RM9122=y
+CONFIG_SERIAL_RM9000=y
+CONFIG_GPI_RM9000=y
+CONFIG_WDT_RM9000=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
 
 #
@@ -101,6 +109,7 @@
 CONFIG_CPU_RM9000=y
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_RM9000=y
+CONFIG_WEAK_ORDERING=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@@ -117,8 +126,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -136,6 +145,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -149,6 +159,7 @@
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_PREEMPT_BKL=y
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -168,15 +179,20 @@
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -184,12 +200,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -207,6 +223,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -249,6 +266,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -262,6 +287,8 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -282,10 +309,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -315,7 +345,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -342,7 +371,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -364,11 +393,13 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -420,6 +451,7 @@
 # CONFIG_MTD_NAND_ECC_SMC is not set
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
 
 #
@@ -455,6 +487,12 @@
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -464,6 +502,8 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+# CONFIG_SCSI_NETLINK is not set
 # CONFIG_SCSI_PROC_FS is not set
 
 #
@@ -482,14 +522,17 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
 
 #
 # SCSI low-level drivers
@@ -502,26 +545,35 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+CONFIG_SCSI_AIC94XX=m
+# CONFIG_AIC94XX_DEBUG is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -585,14 +637,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -632,6 +687,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -707,6 +763,7 @@
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+CONFIG_WDT_RM9K_GPI=m
 
 #
 # PCI-based Watchdog Cards
@@ -724,10 +781,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -735,7 +788,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -751,6 +803,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -759,14 +812,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -782,6 +830,7 @@
 # CONFIG_FB_CFB_FILLRECT is not set
 # CONFIG_FB_CFB_COPYAREA is not set
 # CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
@@ -798,6 +847,7 @@
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
@@ -831,6 +881,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -843,8 +899,8 @@
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -854,9 +910,11 @@
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
@@ -884,14 +942,13 @@
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
 #
 CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 # CONFIG_USB_HIDDEV is not set
@@ -913,6 +970,7 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -927,6 +985,7 @@
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 # CONFIG_USB_MON is not set
 
@@ -944,19 +1003,21 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX 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_CY7C63 is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1014,16 +1075,26 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1034,6 +1105,7 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -1056,11 +1128,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -1072,7 +1146,6 @@
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
@@ -1107,7 +1180,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1179,6 +1251,14 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1188,11 +1268,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1206,16 +1288,27 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
 # CONFIG_CRYPTO_HMAC is not set
+CONFIG_CRYPTO_XCBC=m
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
+CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 # CONFIG_CRYPTO_DES is not set
+CONFIG_CRYPTO_FCRYPT=m
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -1229,6 +1322,7 @@
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1238,6 +1332,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
@@ -1245,3 +1340,5 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index f9812d1..864de21 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:10 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:48 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,13 +64,18 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_ARC=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
@@ -123,8 +128,8 @@
 CONFIG_BOARD_SCACHE=y
 CONFIG_IP22_CPU_SCACHE=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -141,6 +146,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -153,6 +159,7 @@
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -171,16 +178,21 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 # CONFIG_HOTPLUG is not set
@@ -188,12 +200,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -211,6 +223,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -238,7 +251,6 @@
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
 
 #
 # PCI Hotplug Support
@@ -252,6 +264,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -265,7 +285,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -286,10 +309,13 @@
 CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -331,11 +357,17 @@
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=y
 CONFIG_INET6_XFRM_TUNNEL=m
 CONFIG_INET6_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_TRANSPORT=m
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
 CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -346,19 +378,43 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
 CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
@@ -375,60 +431,45 @@
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_CT_ACCT=y
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CONNTRACK_SECMARK=y
-CONFIG_IP_NF_CONNTRACK_EVENTS=y
-CONFIG_IP_NF_CONNTRACK_NETLINK=m
-# CONFIG_IP_NF_CT_PROTO_SCTP is not set
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_PPTP=m
-CONFIG_IP_NF_H323=m
-CONFIG_IP_NF_SIP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_MATCH_OWNER=m
 CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_NAT_PPTP=m
-CONFIG_IP_NF_NAT_H323=m
-CONFIG_IP_NF_NAT_SIP=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
 CONFIG_IP_NF_TARGET_TTL=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
@@ -439,6 +480,7 @@
 #
 # IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
+CONFIG_NF_CONNTRACK_IPV6=m
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_RT=m
@@ -448,6 +490,7 @@
 CONFIG_IP6_NF_MATCH_OWNER=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_MH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
@@ -484,7 +527,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-CONFIG_NET_DIVERT=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -492,6 +534,7 @@
 # QoS and/or fair queueing
 #
 CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FIFO=y
 # CONFIG_NET_SCH_CLK_JIFFIES is not set
 CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
 # CONFIG_NET_SCH_CLK_CPU is not set
@@ -546,6 +589,7 @@
 CONFIG_IEEE80211_SOFTMAC=m
 # CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
 CONFIG_WIRELESS_EXT=y
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -556,7 +600,6 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -592,6 +635,10 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -601,6 +648,8 @@
 #
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -620,24 +669,30 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=m
 # CONFIG_SCSI_FC_ATTRS is not set
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
 CONFIG_ISCSI_TCP=m
 CONFIG_SGIWD93_SCSI=y
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
@@ -679,6 +734,8 @@
 CONFIG_CICADA_PHY=m
 # CONFIG_VITESSE_PHY is not set
 # CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -730,6 +787,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -752,6 +810,7 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=m
 CONFIG_MOUSE_SERIAL=m
@@ -815,10 +874,6 @@
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 CONFIG_RAW_DRIVER=m
 CONFIG_MAX_RAW_DEVS=256
 
@@ -826,7 +881,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -851,14 +905,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -887,6 +936,7 @@
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_SGI_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -894,6 +944,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
@@ -954,6 +1010,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=m
@@ -963,6 +1027,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -974,6 +1039,7 @@
 CONFIG_XFS_SECURITY=y
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=m
 # CONFIG_ROMFS_FS is not set
@@ -987,6 +1053,7 @@
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -994,7 +1061,6 @@
 CONFIG_ISO9660_FS=m
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
-CONFIG_ZISOFS_FS=m
 CONFIG_UDF_FS=m
 CONFIG_UDF_NLS=y
 
@@ -1013,17 +1079,20 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -1142,6 +1211,14 @@
 CONFIG_NLS_UTF8=m
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1151,11 +1228,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1170,18 +1249,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1193,6 +1284,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1202,6 +1294,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=m
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=m
 CONFIG_CRC32=m
@@ -1213,3 +1306,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index f21186c..7b2f5f8 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:10 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:49 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -70,10 +70,14 @@
 # CONFIG_REPLICATE_EXHANDLERS is not set
 CONFIG_EARLY_PRINTK=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_ARC=y
 CONFIG_DMA_IP27=y
 CONFIG_CPU_BIG_ENDIAN=y
@@ -121,8 +125,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
@@ -145,8 +149,10 @@
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
 CONFIG_SMP=y
 CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_NR_CPUS_DEFAULT_64=y
 CONFIG_NR_CPUS=64
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
@@ -162,6 +168,7 @@
 # CONFIG_PREEMPT is not set
 CONFIG_PREEMPT_BKL=y
 # CONFIG_MIPS_INSANE_LARGE is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -180,17 +187,22 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CPUSETS=y
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -198,12 +210,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -222,6 +234,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
@@ -263,11 +276,20 @@
 # CONFIG_BUILD_ELF64 is not set
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
 CONFIG_MIPS32_O32=y
 CONFIG_MIPS32_N32=y
 CONFIG_BINFMT_ELF32=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -281,7 +303,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -302,10 +327,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -335,7 +363,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -343,6 +370,7 @@
 # QoS and/or fair queueing
 #
 CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FIFO=y
 # CONFIG_NET_SCH_CLK_JIFFIES is not set
 CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
 # CONFIG_NET_SCH_CLK_CPU is not set
@@ -374,6 +402,7 @@
 CONFIG_NET_CLS_FW=m
 CONFIG_NET_CLS_U32=m
 # CONFIG_CLS_U32_PERF is not set
+CONFIG_CLS_U32_MARK=y
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
 # CONFIG_NET_EMATCH is not set
@@ -448,6 +477,12 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -457,6 +492,8 @@
 #
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -476,14 +513,17 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
 
 #
 # SCSI low-level drivers
@@ -496,24 +536,33 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+CONFIG_SCSI_AIC94XX=m
+# CONFIG_AIC94XX_DEBUG is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 CONFIG_SCSI_QLOGIC_1280=y
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -529,6 +578,7 @@
 CONFIG_MD_MULTIPATH=m
 CONFIG_MD_FAULTY=m
 CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
@@ -583,6 +633,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -619,14 +671,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -724,10 +779,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -735,7 +786,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -760,14 +810,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -779,6 +824,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -848,6 +894,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -859,6 +913,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 CONFIG_JBD_DEBUG=y
 CONFIG_FS_MBCACHE=y
@@ -870,6 +925,7 @@
 CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -881,6 +937,7 @@
 CONFIG_AUTOFS_FS=m
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -900,17 +957,20 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -942,7 +1002,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -975,6 +1034,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -984,11 +1051,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=15
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1003,7 +1072,12 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
@@ -1012,9 +1086,16 @@
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1026,6 +1107,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1035,6 +1117,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1042,3 +1125,5 @@
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index 61e069a..14398e8 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:11 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:50 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,15 +64,17 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_ARC=y
-CONFIG_DMA_IP32=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
-CONFIG_OWN_DMA=y
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
@@ -124,8 +126,8 @@
 CONFIG_R5000_CPU_SCACHE=y
 CONFIG_RM7000_CPU_SCACHE=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
@@ -141,6 +143,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -153,6 +156,7 @@
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -171,16 +175,21 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -188,12 +197,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -206,6 +215,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
@@ -246,11 +256,20 @@
 # CONFIG_BUILD_ELF64 is not set
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
 CONFIG_MIPS32_O32=y
 # CONFIG_MIPS32_N32 is not set
 CONFIG_BINFMT_ELF32=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -264,7 +283,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -284,10 +306,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -317,7 +342,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -393,6 +417,12 @@
 CONFIG_ATA_OVER_ETH=y
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=y
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -402,6 +432,8 @@
 #
 CONFIG_RAID_ATTRS=y
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -421,14 +453,17 @@
 CONFIG_SCSI_MULTI_LUN=y
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 CONFIG_SCSI_SAS_ATTRS=y
+CONFIG_SCSI_SAS_LIBSAS=y
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
 
 #
 # SCSI low-level drivers
@@ -446,24 +481,33 @@
 CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+CONFIG_SCSI_AIC94XX=y
+# CONFIG_AIC94XX_DEBUG is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -517,6 +561,8 @@
 CONFIG_CICADA_PHY=y
 CONFIG_VITESSE_PHY=y
 CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -553,14 +599,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=y
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=y
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=y
 
 #
 # Token Ring devices
@@ -600,6 +649,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -678,10 +728,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -689,7 +735,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -714,14 +759,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -739,6 +779,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -746,6 +787,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -808,16 +855,26 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -828,6 +885,7 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=y
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -847,17 +905,20 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=y
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -888,7 +949,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -917,6 +977,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=y
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -926,12 +994,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
-# CONFIG_UNWIND_INFO is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -946,7 +1015,12 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
 CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
@@ -955,9 +1029,16 @@
 CONFIG_CRYPTO_SHA512=y
 CONFIG_CRYPTO_WP512=y
 CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_LRW=y
 CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=y
 CONFIG_CRYPTO_BLOWFISH=y
 CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
 CONFIG_CRYPTO_SERPENT=y
 CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_CAST5=y
@@ -969,6 +1050,7 @@
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CAMELLIA=y
 
 #
 # Hardware crypto devices
@@ -977,6 +1059,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=y
 CONFIG_CRC32=y
@@ -984,3 +1067,5 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig
index 8896666..b389787 100644
--- a/arch/mips/configs/jaguar-atx_defconfig
+++ b/arch/mips/configs/jaguar-atx_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:12 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:51 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -65,10 +65,14 @@
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_JAGUAR_DMALOW=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_LIMITED_DMA=y
@@ -106,6 +110,7 @@
 CONFIG_CPU_RM9000=y
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_RM9000=y
+CONFIG_WEAK_ORDERING=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@@ -124,8 +129,8 @@
 CONFIG_RM7000_CPU_SCACHE=y
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -141,6 +146,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -171,14 +177,19 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -186,12 +197,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -208,6 +219,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -249,6 +261,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -277,13 +297,15 @@
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_IPV6=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
@@ -294,6 +316,8 @@
 CONFIG_INET6_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_TRANSPORT=m
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_IPV6_SIT=m
 CONFIG_IPV6_TUNNEL=m
 CONFIG_NETWORK_SECMARK=y
 # CONFIG_NETFILTER is not set
@@ -369,6 +393,11 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -378,6 +407,12 @@
 #
 CONFIG_RAID_ATTRS=m
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -428,6 +463,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -475,6 +512,7 @@
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
@@ -483,14 +521,17 @@
 CONFIG_MV643XX_ETH_0=y
 CONFIG_MV643XX_ETH_1=y
 CONFIG_MV643XX_ETH_2=y
+CONFIG_QLA3XXX=m
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -574,10 +615,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -608,14 +645,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -627,6 +659,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -695,14 +728,23 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -712,6 +754,7 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -731,8 +774,10 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 
@@ -752,6 +797,7 @@
 #
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
+# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
@@ -759,7 +805,6 @@
 CONFIG_SUNRPC=y
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 
@@ -779,11 +824,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -798,6 +845,10 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
@@ -807,9 +858,14 @@
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -821,6 +877,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -830,6 +887,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=m
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=m
 CONFIG_CRC32=m
@@ -837,3 +895,5 @@
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig
index 835764d..dacf0a6 100644
--- a/arch/mips/configs/jazz_defconfig
+++ b/arch/mips/configs/jazz_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc1
-# Sun Oct  8 19:03:07 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:52 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -40,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -65,11 +67,14 @@
 # CONFIG_MIPS_MAGNUM_4000 is not set
 CONFIG_OLIVETTI_M700=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_ARC=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_DMA_NONCOHERENT=y
@@ -140,6 +145,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 CONFIG_HZ_100=y
 # CONFIG_HZ_128 is not set
@@ -152,6 +158,7 @@
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -171,6 +178,7 @@
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
@@ -179,8 +187,8 @@
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
@@ -257,6 +265,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -271,7 +287,9 @@
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=m
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -298,6 +316,7 @@
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -317,8 +336,8 @@
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
 CONFIG_IPV6_TUNNEL=m
-# CONFIG_IPV6_SUBTREES is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
@@ -331,16 +350,39 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 # CONFIG_NETFILTER_XT_TARGET_DSCP is not set
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
 # CONFIG_NETFILTER_XT_TARGET_CONNSECMARK is not set
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
@@ -362,25 +404,13 @@
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CONNTRACK_SECMARK=y
-CONFIG_IP_NF_CONNTRACK_EVENTS=y
-CONFIG_IP_NF_CONNTRACK_NETLINK=m
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_PPTP=m
-CONFIG_IP_NF_H323=m
-CONFIG_IP_NF_SIP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
@@ -391,26 +421,25 @@
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_MATCH_OWNER=m
 CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_NAT_PPTP=m
-CONFIG_IP_NF_NAT_H323=m
-CONFIG_IP_NF_NAT_SIP=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -424,6 +453,7 @@
 #
 # IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
+CONFIG_NF_CONNTRACK_IPV6=m
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_RT=m
@@ -433,6 +463,7 @@
 CONFIG_IP6_NF_MATCH_OWNER=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_MH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
@@ -502,6 +533,7 @@
 # QoS and/or fair queueing
 #
 CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FIFO=y
 CONFIG_NET_SCH_CLK_JIFFIES=y
 # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
 # CONFIG_NET_SCH_CLK_CPU is not set
@@ -620,7 +652,6 @@
 #
 CONFIG_BLK_DEV_FD=m
 CONFIG_PARIDE=m
-CONFIG_PARIDE_PARPORT=m
 
 #
 # Parallel IDE high-level drivers
@@ -665,6 +696,10 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -674,6 +709,7 @@
 #
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
 CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
@@ -694,6 +730,7 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
 # SCSI Transports
@@ -802,6 +839,7 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
 # CONFIG_FIXED_PHY is not set
 
 #
@@ -832,7 +870,6 @@
 # CONFIG_AC3200 is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
-# CONFIG_LAN_SAA9730 is not set
 # CONFIG_NET_POCKET is not set
 
 #
@@ -972,17 +1009,12 @@
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -1019,11 +1051,6 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-# CONFIG_TIFM_CORE is not set
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -1054,6 +1081,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
@@ -1114,6 +1147,15 @@
 #
 
 #
+# Auxiliary Display support
+#
+# CONFIG_KS0108 is not set
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=m
@@ -1123,6 +1165,7 @@
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1158,7 +1201,6 @@
 CONFIG_ISO9660_FS=m
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
-CONFIG_ZISOFS_FS=m
 CONFIG_UDF_FS=m
 CONFIG_UDF_NLS=y
 
@@ -1185,7 +1227,7 @@
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -1321,6 +1363,10 @@
 #
 # Distributed Lock Manager
 #
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
 
 #
 # Profiling support
@@ -1335,9 +1381,10 @@
 CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1355,19 +1402,24 @@
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=m
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_TWOFISH_COMMON=m
@@ -1382,6 +1434,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1391,6 +1444,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1402,3 +1456,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index 50fd955..29ed772 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:12 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:53 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,15 +64,20 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 CONFIG_MIPS_TX3927=y
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -114,8 +119,8 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -130,6 +135,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -143,6 +149,7 @@
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_RTC_DS1742=y
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -161,15 +168,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -177,12 +189,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -195,6 +207,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -237,6 +250,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -250,7 +271,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -270,10 +294,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -303,7 +330,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -378,6 +404,12 @@
 CONFIG_ATA_OVER_ETH=y
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=y
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -387,6 +419,12 @@
 #
 CONFIG_RAID_ATTRS=y
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -437,6 +475,8 @@
 CONFIG_CICADA_PHY=y
 CONFIG_VITESSE_PHY=y
 CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -472,14 +512,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=y
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=y
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=y
 
 #
 # Token Ring devices
@@ -518,6 +561,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -565,6 +609,7 @@
 # CONFIG_DIGIEPCA is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
+CONFIG_MOXA_SMARTIO_NEW=y
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_SYNCLINK_GT is not set
@@ -586,6 +631,7 @@
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_TXX9=y
 CONFIG_HAS_TXX9_SERIAL=y
+CONFIG_SERIAL_TXX9_NR_UARTS=6
 # CONFIG_SERIAL_TXX9_CONSOLE is not set
 # CONFIG_SERIAL_TXX9_STDSERIAL is not set
 # CONFIG_SERIAL_JSM is not set
@@ -608,10 +654,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -619,7 +661,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -644,14 +685,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -666,6 +702,7 @@
 # CONFIG_FB_CFB_FILLRECT is not set
 # CONFIG_FB_CFB_COPYAREA is not set
 # CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
@@ -682,6 +719,7 @@
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
@@ -711,6 +749,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -773,14 +816,24 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -810,17 +863,19 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=y
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -849,7 +904,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -867,6 +921,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=y
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -876,12 +938,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
-# CONFIG_UNWIND_INFO is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -896,7 +959,12 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
 CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
@@ -905,9 +973,16 @@
 CONFIG_CRYPTO_SHA512=y
 CONFIG_CRYPTO_WP512=y
 CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_LRW=y
 CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=y
 CONFIG_CRYPTO_BLOWFISH=y
 CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
 CONFIG_CRYPTO_SERPENT=y
 CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_CAST5=y
@@ -919,6 +994,7 @@
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CAMELLIA=y
 
 #
 # Hardware crypto devices
@@ -927,6 +1003,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=y
 CONFIG_CRC32=y
@@ -934,3 +1011,5 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
index 05f539f..a1437b3 100644
--- a/arch/mips/configs/lasat200_defconfig
+++ b/arch/mips/configs/lasat200_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:12 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:54 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 CONFIG_LASAT=y
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -68,10 +68,14 @@
 CONFIG_DS1603=y
 CONFIG_LASAT_SYSCTL=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_MIPS_NILE4=y
@@ -121,8 +125,8 @@
 CONFIG_BOARD_SCACHE=y
 CONFIG_R5000_CPU_SCACHE=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -139,6 +143,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -151,6 +156,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -169,15 +175,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -185,12 +196,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -208,6 +219,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -250,6 +262,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -262,7 +282,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -279,10 +302,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -312,7 +338,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -367,11 +392,13 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -427,6 +454,7 @@
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
+# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -461,9 +489,16 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -500,8 +535,10 @@
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -511,6 +548,7 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_TC86C001=m
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -522,6 +560,12 @@
 #
 CONFIG_RAID_ATTRS=m
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -572,6 +616,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -607,14 +653,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -653,6 +702,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -730,10 +780,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -741,7 +787,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -766,14 +811,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -791,6 +831,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -798,6 +839,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -860,6 +906,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -869,13 +923,15 @@
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -886,6 +942,7 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -905,23 +962,25 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
@@ -947,7 +1006,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -965,6 +1023,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -974,11 +1040,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -993,18 +1061,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1016,6 +1096,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1025,6 +1106,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1032,3 +1114,5 @@
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 96e9410..8d21bb96 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc1
-# Fri Oct  6 17:34:55 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:55 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -40,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -62,11 +64,14 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
@@ -132,8 +137,8 @@
 CONFIG_MIPS_CPU_SCACHE=y
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_MIPS_MT_DISABLED is not set
-# CONFIG_MIPS_MT_SMTC is not set
 CONFIG_MIPS_MT_SMP=y
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_MIPS_MT=y
 CONFIG_SYS_SUPPORTS_MULTITHREADING=y
@@ -157,6 +162,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 CONFIG_SMP=y
 CONFIG_SYS_SUPPORTS_SMP=y
 CONFIG_NR_CPUS=2
@@ -173,6 +179,7 @@
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_PREEMPT_BKL=y
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -192,6 +199,7 @@
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
@@ -199,8 +207,8 @@
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_CPUSETS is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
@@ -259,7 +267,6 @@
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
-# CONFIG_PCI_MULTITHREAD_PROBE is not set
 CONFIG_MMU=y
 
 #
@@ -280,6 +287,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -294,7 +309,9 @@
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 # CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
@@ -302,7 +319,6 @@
 # CONFIG_IP_FIB_TRIE is not set
 CONFIG_IP_FIB_HASH=y
 CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_FWMARK=y
 CONFIG_IP_ROUTE_MULTIPATH=y
 # CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
 CONFIG_IP_ROUTE_VERBOSE=y
@@ -331,6 +347,7 @@
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -379,8 +396,8 @@
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
 CONFIG_IPV6_TUNNEL=m
-# CONFIG_IPV6_SUBTREES is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
@@ -393,15 +410,37 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 # CONFIG_NETFILTER_XT_TARGET_DSCP is not set
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
 # CONFIG_NETFILTER_XT_TARGET_CONNSECMARK is not set
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
@@ -425,25 +464,13 @@
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_CT_ACCT=y
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CONNTRACK_SECMARK=y
-CONFIG_IP_NF_CONNTRACK_EVENTS=y
-CONFIG_IP_NF_CONNTRACK_NETLINK=m
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_PPTP=m
-CONFIG_IP_NF_H323=m
-CONFIG_IP_NF_SIP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
@@ -454,26 +481,25 @@
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_MATCH_OWNER=m
 CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_NAT_PPTP=m
-CONFIG_IP_NF_NAT_H323=m
-CONFIG_IP_NF_NAT_SIP=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -487,6 +513,7 @@
 #
 # IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
+CONFIG_NF_CONNTRACK_IPV6=m
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_RT=m
@@ -496,6 +523,7 @@
 CONFIG_IP6_NF_MATCH_OWNER=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_MH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
@@ -568,6 +596,7 @@
 # QoS and/or fair queueing
 #
 CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FIFO=y
 CONFIG_NET_SCH_CLK_JIFFIES=y
 # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
 # CONFIG_NET_SCH_CLK_CPU is not set
@@ -655,6 +684,7 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
@@ -718,6 +748,7 @@
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
+# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -757,6 +788,12 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
@@ -801,6 +838,7 @@
 # CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -810,6 +848,7 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_TC86C001=m
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -821,6 +860,7 @@
 #
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=m
+CONFIG_SCSI_TGT=m
 CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
@@ -841,6 +881,7 @@
 CONFIG_SCSI_MULTI_LUN=y
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
 # SCSI Transports
@@ -889,6 +930,7 @@
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
 
 #
 # Serial ATA (prod) and Parallel ATA (experimental) drivers
@@ -964,6 +1006,7 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
 # CONFIG_FIXED_PHY is not set
 
 #
@@ -1002,7 +1045,7 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_LAN_SAA9730 is not set
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -1022,14 +1065,17 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 # CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -1146,10 +1192,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -1157,7 +1199,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -1182,11 +1223,6 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-# CONFIG_TIFM_CORE is not set
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -1215,6 +1251,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=m
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -1277,6 +1319,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1286,6 +1336,7 @@
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1327,7 +1378,6 @@
 CONFIG_ISO9660_FS=m
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
-CONFIG_ZISOFS_FS=m
 CONFIG_UDF_FS=m
 CONFIG_UDF_NLS=y
 
@@ -1365,6 +1415,20 @@
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EFS_FS=m
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
 CONFIG_CRAMFS=m
 CONFIG_VXFS_FS=m
 # CONFIG_HPFS_FS is not set
@@ -1470,9 +1534,10 @@
 CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=15
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1489,19 +1554,24 @@
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=m
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_TWOFISH_COMMON=m
@@ -1516,6 +1586,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1525,6 +1596,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1536,3 +1608,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index 03efcfd..2acb99b 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:13 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:56 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,10 +64,14 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
@@ -117,8 +121,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -136,6 +140,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -148,6 +153,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -166,15 +172,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -183,12 +194,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -206,6 +217,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_LSF is not set
 
@@ -244,6 +256,13 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -257,7 +276,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
@@ -286,10 +308,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -324,7 +349,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-CONFIG_NET_DIVERT=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -332,6 +356,7 @@
 # QoS and/or fair queueing
 #
 CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FIFO=y
 CONFIG_NET_SCH_CLK_JIFFIES=y
 # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
 # CONFIG_NET_SCH_CLK_CPU is not set
@@ -377,6 +402,7 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_IEEE80211 is not set
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -389,6 +415,7 @@
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -423,6 +450,10 @@
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -432,6 +463,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -468,7 +505,6 @@
 # Ethernet (10 or 100Mbit)
 #
 # CONFIG_NET_ETHERNET is not set
-# CONFIG_MIPS_SIM_NET is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -512,6 +548,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -579,17 +616,12 @@
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -605,6 +637,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -613,14 +646,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -639,6 +667,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
@@ -699,16 +732,26 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
 # CONFIG_INOTIFY is not set
@@ -736,6 +779,7 @@
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
 # CONFIG_SYSFS is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
@@ -776,7 +820,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -794,6 +837,10 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -803,23 +850,29 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DETECT_SOFTLOCKUP is not set
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
@@ -838,7 +891,12 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
@@ -847,7 +905,13 @@
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 # CONFIG_CRYPTO_DES is not set
+CONFIG_CRYPTO_FCRYPT=m
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -861,6 +925,7 @@
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -870,8 +935,11 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=y
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
index e4221aa..d52a5a4 100644
--- a/arch/mips/configs/mpc30x_defconfig
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc2
-# Tue Jul 25 23:16:46 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:56 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 CONFIG_MACH_VR41XX=y
 # CONFIG_PMC_YOSEMITE is not set
@@ -71,10 +71,14 @@
 # CONFIG_ZAO_CAPCELLA is not set
 CONFIG_PCI_VR41XX=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
@@ -107,6 +111,7 @@
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_VR41XX=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
@@ -120,8 +125,8 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -136,6 +141,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -148,6 +154,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -166,16 +173,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -183,12 +194,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -206,6 +217,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -261,6 +273,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -274,7 +294,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -292,10 +315,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -325,7 +351,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -399,9 +424,16 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -431,6 +463,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -492,14 +530,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -594,6 +635,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -665,10 +707,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 
 #
@@ -684,7 +722,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -709,14 +746,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -735,6 +767,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -742,6 +775,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -754,8 +793,8 @@
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -764,7 +803,8 @@
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
@@ -782,7 +822,6 @@
 #
 # may also be needed; see USB_STORAGE Help for more information
 #
-# CONFIG_USB_STORAGE is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -807,6 +846,7 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -820,6 +860,7 @@
 # CONFIG_USB_KAWETH is not set
 CONFIG_USB_PEGASUS=m
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 # CONFIG_USB_MON is not set
 
@@ -837,6 +878,7 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
@@ -844,11 +886,12 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -906,16 +949,26 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -945,17 +998,19 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -1000,6 +1055,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1009,11 +1072,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="mem=32M console=ttyVR0,19200 ide0=0x170,0x376,73"
 
@@ -1028,18 +1093,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1051,6 +1128,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1060,6 +1138,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1067,3 +1146,5 @@
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
index 32b1afd..746106b 100644
--- a/arch/mips/configs/ocelot_3_defconfig
+++ b/arch/mips/configs/ocelot_3_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:15 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:58 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,10 +64,14 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_CPU_BIG_ENDIAN=y
@@ -104,6 +108,7 @@
 CONFIG_CPU_RM9000=y
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_RM9000=y
+CONFIG_WEAK_ORDERING=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@@ -122,8 +127,8 @@
 CONFIG_RM7000_CPU_SCACHE=y
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -141,6 +146,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -153,6 +159,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -171,16 +178,21 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -188,12 +200,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -211,6 +223,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -253,6 +266,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -266,7 +287,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -283,13 +307,16 @@
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -302,11 +329,17 @@
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 # CONFIG_INET6_IPCOMP is not set
+CONFIG_IPV6_MIP6=y
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
 CONFIG_INET6_XFRM_MODE_TRANSPORT=m
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
 # CONFIG_IPV6_TUNNEL is not set
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -317,15 +350,42 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
-# CONFIG_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
@@ -336,14 +396,17 @@
 CONFIG_NETFILTER_XT_MATCH_QUOTA=m
 CONFIG_NETFILTER_XT_MATCH_REALM=m
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -351,6 +414,7 @@
 #
 # IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
+CONFIG_NF_CONNTRACK_IPV6=m
 # CONFIG_IP6_NF_QUEUE is not set
 # CONFIG_IP6_NF_IPTABLES is not set
 
@@ -377,7 +441,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -401,6 +464,7 @@
 CONFIG_IEEE80211_SOFTMAC=m
 # CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
 CONFIG_WIRELESS_EXT=y
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -451,6 +515,12 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -460,6 +530,8 @@
 #
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=m
+CONFIG_SCSI_TGT=m
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -478,14 +550,17 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 CONFIG_SCSI_FC_ATTRS=m
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
 
 #
 # SCSI low-level drivers
@@ -498,26 +573,35 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+CONFIG_SCSI_AIC94XX=m
+# CONFIG_AIC94XX_DEBUG is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -571,6 +655,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -607,7 +693,7 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_LAN_SAA9730 is not set
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -630,14 +716,18 @@
 CONFIG_MV643XX_ETH_0=y
 CONFIG_MV643XX_ETH_1=y
 CONFIG_MV643XX_ETH_2=y
+CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -665,6 +755,7 @@
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
@@ -685,6 +776,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -758,10 +850,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -769,7 +857,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -794,14 +881,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -816,6 +898,7 @@
 # CONFIG_FB_CFB_FILLRECT is not set
 # CONFIG_FB_CFB_COPYAREA is not set
 # CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
 CONFIG_FB_MODE_HELPERS=y
@@ -832,6 +915,7 @@
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
@@ -868,6 +952,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -930,6 +1020,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -939,6 +1037,7 @@
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=m
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -947,12 +1046,13 @@
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_REISERFS_FS_XATTR is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=m
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -963,6 +1063,7 @@
 CONFIG_AUTOFS_FS=y
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -982,11 +1083,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -1029,7 +1132,6 @@
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1086,6 +1188,14 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1095,11 +1205,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="ip=any root=nfs"
 
@@ -1113,18 +1225,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1136,6 +1260,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1145,6 +1270,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1156,3 +1282,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
index ebe75c1..4b32b27 100644
--- a/arch/mips/configs/ocelot_c_defconfig
+++ b/arch/mips/configs/ocelot_c_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:16 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:58 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,10 +64,14 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_CPU_BIG_ENDIAN=y
@@ -120,8 +124,8 @@
 CONFIG_RM7000_CPU_SCACHE=y
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
@@ -138,6 +142,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -150,6 +155,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -168,15 +174,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -184,12 +195,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -202,6 +213,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
@@ -242,11 +254,20 @@
 # CONFIG_BUILD_ELF64 is not set
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
 CONFIG_MIPS32_O32=y
 CONFIG_MIPS32_N32=y
 CONFIG_BINFMT_ELF32=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -259,7 +280,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -279,10 +303,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -312,7 +339,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -387,6 +413,12 @@
 CONFIG_ATA_OVER_ETH=y
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=y
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -396,6 +428,12 @@
 #
 CONFIG_RAID_ATTRS=y
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -446,6 +484,8 @@
 CONFIG_CICADA_PHY=y
 CONFIG_VITESSE_PHY=y
 CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -482,14 +522,17 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 # CONFIG_MV643XX_ETH is not set
+CONFIG_QLA3XXX=y
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=y
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=y
 
 #
 # Token Ring devices
@@ -528,6 +571,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -605,10 +649,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -616,7 +656,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -641,14 +680,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -666,6 +700,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -673,6 +708,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -735,16 +775,26 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -755,6 +805,7 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=y
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -774,17 +825,20 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=y
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -816,7 +870,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -834,6 +887,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=y
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -843,12 +904,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
-# CONFIG_UNWIND_INFO is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -863,7 +925,12 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
 CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
@@ -872,9 +939,16 @@
 CONFIG_CRYPTO_SHA512=y
 CONFIG_CRYPTO_WP512=y
 CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_LRW=y
 CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=y
 CONFIG_CRYPTO_BLOWFISH=y
 CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
 CONFIG_CRYPTO_SERPENT=y
 CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_CAST5=y
@@ -886,6 +960,7 @@
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CAMELLIA=y
 
 #
 # Hardware crypto devices
@@ -894,6 +969,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=y
 CONFIG_CRC32=y
@@ -901,3 +977,5 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig
index 5a9603c..674631b 100644
--- a/arch/mips/configs/ocelot_defconfig
+++ b/arch/mips/configs/ocelot_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:16 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:59 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,10 +64,14 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_CPU_BIG_ENDIAN=y
@@ -123,8 +127,8 @@
 CONFIG_RM7000_CPU_SCACHE=y
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -142,6 +146,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -154,6 +159,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -172,15 +178,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 # CONFIG_HOTPLUG is not set
@@ -188,12 +199,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -206,6 +217,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -233,7 +245,6 @@
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
 
 #
 # PCI Hotplug Support
@@ -247,6 +258,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -259,7 +278,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -279,10 +301,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -312,7 +337,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -345,7 +369,6 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -382,6 +405,10 @@
 CONFIG_ATA_OVER_ETH=y
 
 #
+# Misc devices
+#
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -391,6 +418,12 @@
 #
 CONFIG_RAID_ATTRS=y
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -434,6 +467,8 @@
 CONFIG_CICADA_PHY=y
 CONFIG_VITESSE_PHY=y
 CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -484,6 +519,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -557,17 +593,12 @@
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -592,14 +623,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -617,6 +643,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -624,6 +651,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
@@ -684,16 +716,26 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -704,6 +746,7 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=y
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -723,17 +766,20 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=y
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -765,7 +811,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -783,6 +828,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=y
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -792,12 +845,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
-# CONFIG_UNWIND_INFO is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -812,7 +866,12 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
 CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
@@ -821,9 +880,16 @@
 CONFIG_CRYPTO_SHA512=y
 CONFIG_CRYPTO_WP512=y
 CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_LRW=y
 CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=y
 CONFIG_CRYPTO_BLOWFISH=y
 CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
 CONFIG_CRYPTO_SERPENT=y
 CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_CAST5=y
@@ -835,6 +901,7 @@
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CAMELLIA=y
 
 #
 # Hardware crypto devices
@@ -843,6 +910,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=y
 CONFIG_CRC32=y
@@ -850,3 +918,5 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig
index 46a942c..2600263 100644
--- a/arch/mips/configs/ocelot_g_defconfig
+++ b/arch/mips/configs/ocelot_g_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:16 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:00 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,10 +64,14 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_CPU_BIG_ENDIAN=y
@@ -106,15 +110,14 @@
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_RM7000=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
 #
 # Kernel type
 #
-# CONFIG_32BIT is not set
-CONFIG_64BIT=y
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -123,9 +126,10 @@
 CONFIG_RM7000_CPU_SCACHE=y
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -141,6 +145,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -153,6 +158,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -171,15 +177,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -187,12 +198,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -205,7 +216,10 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LSF=y
 
 #
 # IO Schedulers
@@ -242,12 +256,15 @@
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_BUILD_ELF64 is not set
-CONFIG_MIPS32_COMPAT=y
-CONFIG_COMPAT=y
-CONFIG_MIPS32_O32=y
-CONFIG_MIPS32_N32=y
-CONFIG_BINFMT_ELF32=y
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
 
 #
 # Networking
@@ -262,7 +279,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -282,10 +302,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -315,7 +338,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -390,6 +412,12 @@
 CONFIG_ATA_OVER_ETH=y
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=y
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -399,6 +427,12 @@
 #
 CONFIG_RAID_ATTRS=y
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -449,6 +483,8 @@
 CONFIG_CICADA_PHY=y
 CONFIG_VITESSE_PHY=y
 CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -485,14 +521,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=y
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=y
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=y
 
 #
 # Token Ring devices
@@ -531,6 +570,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -608,10 +648,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -619,7 +655,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -644,14 +679,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -669,6 +699,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -676,6 +707,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -738,16 +774,26 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -758,6 +804,7 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=y
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -777,17 +824,20 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=y
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -819,7 +869,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -837,6 +886,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=y
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -846,12 +903,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
-# CONFIG_UNWIND_INFO is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -866,7 +924,12 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
 CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
@@ -875,9 +938,16 @@
 CONFIG_CRYPTO_SHA512=y
 CONFIG_CRYPTO_WP512=y
 CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_LRW=y
 CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=y
 CONFIG_CRYPTO_BLOWFISH=y
 CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
 CONFIG_CRYPTO_SERPENT=y
 CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_CAST5=y
@@ -889,6 +959,7 @@
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CAMELLIA=y
 
 #
 # Hardware crypto devices
@@ -897,6 +968,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=y
 CONFIG_CRC32=y
@@ -904,3 +976,5 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 7d3c688..05a33a2 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:17 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:01 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,14 +64,19 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 CONFIG_SOC_AU1100=y
 CONFIG_SOC_AU1X00=y
@@ -117,8 +122,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
 CONFIG_CPU_HAS_LLSC=y
@@ -136,6 +141,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -148,6 +154,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -166,15 +173,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -182,12 +194,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -205,6 +217,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -253,6 +266,10 @@
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
 # CONFIG_PM is not set
 
 #
@@ -269,7 +286,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -290,10 +310,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -312,15 +335,42 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
-# CONFIG_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
@@ -331,14 +381,17 @@
 CONFIG_NETFILTER_XT_MATCH_QUOTA=m
 CONFIG_NETFILTER_XT_MATCH_REALM=m
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -366,7 +419,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -422,11 +474,13 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -511,6 +565,10 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -520,6 +578,12 @@
 #
 CONFIG_RAID_ATTRS=m
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -563,6 +627,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -609,6 +675,7 @@
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -628,6 +695,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -707,10 +775,6 @@
 # CONFIG_R3964 is not set
 
 #
-# Ftape, the floppy tape device driver
-#
-
-#
 # PCMCIA character devices
 #
 CONFIG_SYNCLINK_CS=m
@@ -722,7 +786,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -747,14 +810,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -772,6 +830,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -779,6 +838,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -840,6 +904,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -851,6 +923,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -863,6 +936,7 @@
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -873,6 +947,7 @@
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -892,23 +967,25 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
@@ -937,7 +1014,6 @@
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -994,6 +1070,14 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1003,11 +1087,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1022,18 +1108,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1045,6 +1143,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1054,6 +1153,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1065,3 +1165,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index a77805a..34a6bee 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:17 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:02 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,14 +64,19 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 CONFIG_SOC_AU1500=y
 CONFIG_SOC_AU1X00=y
@@ -116,8 +121,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
 CONFIG_CPU_HAS_LLSC=y
@@ -134,7 +139,8 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -147,6 +153,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -165,15 +172,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -181,12 +193,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -204,6 +216,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -258,6 +271,10 @@
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
 # CONFIG_PM is not set
 
 #
@@ -274,7 +291,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -295,10 +315,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -317,15 +340,42 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
-# CONFIG_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
@@ -336,14 +386,17 @@
 CONFIG_NETFILTER_XT_MATCH_QUOTA=m
 CONFIG_NETFILTER_XT_MATCH_REALM=m
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -371,7 +424,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -427,11 +479,13 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -487,6 +541,7 @@
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
+# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -522,9 +577,16 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -534,6 +596,7 @@
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -561,8 +624,10 @@
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -572,6 +637,7 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_TC86C001=m
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -583,6 +649,12 @@
 #
 CONFIG_RAID_ATTRS=m
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -633,6 +705,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -670,14 +744,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -718,6 +795,7 @@
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -737,6 +815,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -815,10 +894,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 
 #
@@ -833,7 +908,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -858,14 +932,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -877,6 +946,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -884,6 +954,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -946,6 +1021,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -957,6 +1040,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -969,6 +1053,7 @@
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -979,6 +1064,7 @@
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -998,23 +1084,25 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
@@ -1043,7 +1131,6 @@
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1100,6 +1187,14 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1109,11 +1204,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1128,18 +1225,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1151,6 +1260,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1160,6 +1270,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1171,3 +1282,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index 8318d74..e3bff46 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:17 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:03 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,15 +64,20 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 CONFIG_SOC_AU1550=y
 CONFIG_SOC_AU1X00=y
@@ -117,8 +122,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
 CONFIG_CPU_HAS_LLSC=y
@@ -135,7 +140,8 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -148,6 +154,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -166,15 +173,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -182,12 +194,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -205,6 +217,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -259,6 +272,10 @@
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
 # CONFIG_PM is not set
 
 #
@@ -275,7 +292,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -296,10 +316,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -318,15 +341,42 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
-# CONFIG_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
@@ -337,14 +387,17 @@
 CONFIG_NETFILTER_XT_MATCH_QUOTA=m
 CONFIG_NETFILTER_XT_MATCH_REALM=m
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -372,7 +425,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -428,11 +480,13 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -488,6 +542,7 @@
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
+# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -523,9 +578,16 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -535,6 +597,7 @@
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -562,8 +625,10 @@
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -573,6 +638,7 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_TC86C001=m
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -584,6 +650,12 @@
 #
 CONFIG_RAID_ATTRS=m
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -634,6 +706,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -671,14 +745,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -711,6 +788,7 @@
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -730,6 +808,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -808,10 +887,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 
 #
@@ -826,7 +901,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -851,14 +925,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -870,6 +939,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -877,6 +947,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -939,6 +1014,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -950,6 +1033,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -962,6 +1046,7 @@
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -972,6 +1057,7 @@
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -991,23 +1077,25 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
@@ -1036,7 +1124,6 @@
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1093,6 +1180,14 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1102,11 +1197,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1121,18 +1218,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1144,6 +1253,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1153,6 +1263,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1164,3 +1275,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
index fcb8fea..009b3f8 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc2
-# Sat Oct 14 23:01:16 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:04 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -40,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 CONFIG_PNX8550_JBS=y
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -62,11 +64,14 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
@@ -134,6 +139,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -146,6 +152,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -165,6 +172,7 @@
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
@@ -172,6 +180,7 @@
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -231,7 +240,6 @@
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
-# CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
 CONFIG_MMU=y
 
@@ -253,6 +261,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -267,6 +283,7 @@
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -293,6 +310,7 @@
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -350,6 +368,7 @@
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -393,6 +412,12 @@
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
@@ -436,6 +461,7 @@
 # CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -445,6 +471,7 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_TC86C001=m
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -456,6 +483,7 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
 CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
@@ -475,6 +503,7 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
 # SCSI Transports
@@ -518,6 +547,7 @@
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
 
 #
 # Serial ATA (prod) and Parallel ATA (experimental) drivers
@@ -605,7 +635,7 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_LAN_SAA9730 is not set
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -625,14 +655,17 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 # CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -720,7 +753,10 @@
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_IP3106 is not set
+CONFIG_SERIAL_PNX8XXX=y
+CONFIG_SERIAL_PNX8XXX_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
@@ -741,10 +777,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -752,7 +784,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -768,6 +799,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -776,15 +808,11 @@
 # CONFIG_HWMON_VID is not set
 # CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Misc devices
-#
-# CONFIG_TIFM_CORE is not set
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -814,6 +842,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -826,8 +859,8 @@
 # Miscellaneous USB options
 #
 # CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -836,7 +869,8 @@
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
@@ -890,7 +924,7 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -905,6 +939,7 @@
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 CONFIG_USB_MON=y
 
@@ -935,6 +970,7 @@
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB DSL modem support
@@ -991,6 +1027,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1041,7 +1085,7 @@
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -1137,6 +1181,14 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1149,28 +1201,29 @@
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 CONFIG_DEBUG_SLAB=y
 # CONFIG_DEBUG_SLAB_LEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_RWSEMS is not set
 # CONFIG_DEBUG_LOCK_ALLOC is not set
 # CONFIG_PROVE_LOCKING is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
-# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
@@ -1189,21 +1242,27 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
 CONFIG_CRYPTO_MANAGER=m
 # CONFIG_CRYPTO_HMAC is not set
+CONFIG_CRYPTO_XCBC=m
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_GF128MUL=m
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 # CONFIG_CRYPTO_DES is not set
+CONFIG_CRYPTO_FCRYPT=m
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -1217,6 +1276,7 @@
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1226,8 +1286,11 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig
index f38a2c1..5bd377b 100644
--- a/arch/mips/configs/pnx8550-stb810_defconfig
+++ b/arch/mips/configs/pnx8550-stb810_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19
-# Thu Dec  7 16:35:12 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:04 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -58,17 +59,19 @@
 # CONFIG_SIBYTE_LITTLESUR is not set
 # CONFIG_SIBYTE_CRHINE is not set
 # CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_SNI_RM is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
-# CONFIG_KEXEC is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
@@ -136,6 +139,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -148,6 +152,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -167,6 +172,7 @@
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
@@ -234,7 +240,6 @@
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
-# CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
 CONFIG_MMU=y
 
@@ -254,6 +259,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -268,6 +281,7 @@
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -351,6 +365,7 @@
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -443,6 +458,7 @@
 # CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -452,6 +468,7 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_TC86C001=m
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -463,6 +480,7 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
 # CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
@@ -482,6 +500,7 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
 # SCSI Transports
@@ -525,6 +544,7 @@
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
 
 #
 # Serial ATA (prod) and Parallel ATA (experimental) drivers
@@ -608,6 +628,7 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -627,11 +648,13 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 # CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
@@ -775,6 +798,7 @@
 # CONFIG_HWMON_VID is not set
 # CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
@@ -808,6 +832,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -820,9 +849,8 @@
 # Miscellaneous USB options
 #
 # CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_MULTITHREAD_PROBE is not set
+# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -831,7 +859,8 @@
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
@@ -885,6 +914,7 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -987,6 +1017,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1037,7 +1075,7 @@
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -1133,6 +1171,14 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1145,28 +1191,29 @@
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_HEADERS_CHECK=y
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 CONFIG_DEBUG_SLAB=y
 # CONFIG_DEBUG_SLAB_LEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_RWSEMS is not set
 # CONFIG_DEBUG_LOCK_ALLOC is not set
 # CONFIG_PROVE_LOCKING is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
-CONFIG_HEADERS_CHECK=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
@@ -1187,8 +1234,10 @@
 CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=m
 CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
 CONFIG_CRYPTO_MANAGER=m
 # CONFIG_CRYPTO_HMAC is not set
+CONFIG_CRYPTO_XCBC=m
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=m
@@ -1197,9 +1246,13 @@
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_GF128MUL=m
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 # CONFIG_CRYPTO_DES is not set
+CONFIG_CRYPTO_FCRYPT=m
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -1213,6 +1266,7 @@
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1222,8 +1276,11 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig
index 5bc3248..cc69470 100644
--- a/arch/mips/configs/pnx8550-v2pci_defconfig
+++ b/arch/mips/configs/pnx8550-v2pci_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc2
-# Sat Oct 14 23:12:15 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:06 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -40,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 CONFIG_PNX8550_V2PCI=y
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -62,11 +64,14 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
@@ -134,6 +139,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -146,6 +152,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -165,6 +172,7 @@
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
@@ -172,6 +180,7 @@
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -230,7 +239,6 @@
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
-# CONFIG_PCI_MULTITHREAD_PROBE is not set
 CONFIG_MMU=y
 
 #
@@ -251,6 +259,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -265,6 +281,7 @@
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -282,7 +299,7 @@
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
@@ -291,6 +308,7 @@
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -312,7 +330,6 @@
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=m
 # CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_SUBTREES is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
@@ -322,15 +339,38 @@
 # Core Netfilter Configuration
 #
 # CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
 # CONFIG_NETFILTER_XT_MATCH_DSCP is not set
 CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
@@ -341,14 +381,17 @@
 # CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
 CONFIG_NETFILTER_XT_MATCH_REALM=m
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
 # CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -356,6 +399,7 @@
 #
 # IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
+CONFIG_NF_CONNTRACK_IPV6=m
 # CONFIG_IP6_NF_QUEUE is not set
 # CONFIG_IP6_NF_IPTABLES is not set
 
@@ -453,6 +497,12 @@
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
@@ -497,6 +547,7 @@
 # CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -506,6 +557,7 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_TC86C001=m
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -517,6 +569,7 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
 CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
@@ -536,6 +589,7 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
 # SCSI Transports
@@ -584,6 +638,7 @@
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
 
 #
 # Serial ATA (prod) and Parallel ATA (experimental) drivers
@@ -671,7 +726,7 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_LAN_SAA9730 is not set
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -691,14 +746,17 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 # CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -804,6 +862,7 @@
 # CONFIG_DIGIEPCA is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
+CONFIG_MOXA_SMARTIO_NEW=m
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_SYNCLINK_GT is not set
@@ -822,7 +881,10 @@
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_IP3106 is not set
+CONFIG_SERIAL_PNX8XXX=y
+CONFIG_SERIAL_PNX8XXX_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
@@ -843,10 +905,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -854,7 +912,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -883,6 +940,7 @@
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PASEMI is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_I2C_SIS5595 is not set
@@ -918,6 +976,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -951,6 +1010,7 @@
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
@@ -961,17 +1021,13 @@
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Misc devices
-#
-# CONFIG_TIFM_CORE is not set
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -991,6 +1047,7 @@
 # CONFIG_FB_CFB_FILLRECT is not set
 # CONFIG_FB_CFB_COPYAREA is not set
 # CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
@@ -1007,6 +1064,7 @@
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
@@ -1036,6 +1094,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -1048,8 +1112,8 @@
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -1085,7 +1149,6 @@
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_ONETOUCH is not set
 # CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
@@ -1093,7 +1156,6 @@
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 CONFIG_USB_HIDDEV=y
@@ -1109,7 +1171,7 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -1124,6 +1186,7 @@
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 CONFIG_USB_MON=y
 
@@ -1154,6 +1217,7 @@
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1211,6 +1275,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1271,7 +1343,7 @@
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -1368,6 +1440,14 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1380,10 +1460,10 @@
 CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1397,21 +1477,27 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
 CONFIG_CRYPTO_MANAGER=m
 # CONFIG_CRYPTO_HMAC is not set
+CONFIG_CRYPTO_XCBC=m
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_GF128MUL=m
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 # CONFIG_CRYPTO_DES is not set
+CONFIG_CRYPTO_FCRYPT=m
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -1425,6 +1511,7 @@
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1434,6 +1521,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
@@ -1445,3 +1533,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index aa61f0f..c18c5e7 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:18 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:06 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,16 +64,21 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_COHERENT=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_I8259=y
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
 CONFIG_HAVE_STD_PC_SERIAL_PORT=y
@@ -117,8 +122,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -130,9 +135,10 @@
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_STATIC=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 CONFIG_HZ_100=y
 # CONFIG_HZ_128 is not set
@@ -164,12 +170,15 @@
 # CONFIG_SWAP is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 # CONFIG_HOTPLUG is not set
@@ -194,6 +203,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -221,7 +231,6 @@
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
 
 #
 # PCI Hotplug Support
@@ -235,6 +244,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -268,10 +285,12 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -307,7 +326,6 @@
 #
 CONFIG_STANDALONE=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_FW_LOADER is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -343,6 +361,10 @@
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -352,6 +374,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Old CD-ROM drivers (not SCSI, not IDE)
@@ -459,6 +487,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -525,10 +554,6 @@
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
 
 #
@@ -558,14 +583,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -585,6 +605,7 @@
 # CONFIG_VGACON_SOFT_SCROLLBACK is not set
 # CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -592,6 +613,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
@@ -651,14 +678,23 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -668,6 +704,7 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=y
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -687,8 +724,10 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 
@@ -709,6 +748,7 @@
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_DIRECTIO=y
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
@@ -717,7 +757,6 @@
 CONFIG_SUNRPC=y
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 
@@ -737,12 +776,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
-# CONFIG_UNWIND_INFO is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -758,13 +798,12 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index f9e8f41..678f232 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:19 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:07 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -71,10 +71,14 @@
 # CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND is not set
 # CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_GENERIC_ISA_DMA=y
@@ -126,8 +130,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
@@ -143,6 +147,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -155,6 +160,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -173,16 +179,22 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -211,6 +223,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -254,6 +267,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -267,6 +288,8 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -285,13 +308,16 @@
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -304,11 +330,17 @@
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 # CONFIG_INET6_IPCOMP is not set
+CONFIG_IPV6_MIP6=y
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
 CONFIG_INET6_XFRM_MODE_TRANSPORT=m
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
 # CONFIG_IPV6_TUNNEL is not set
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -319,15 +351,42 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
-# CONFIG_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
@@ -338,14 +397,17 @@
 CONFIG_NETFILTER_XT_MATCH_QUOTA=m
 CONFIG_NETFILTER_XT_MATCH_REALM=m
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -353,6 +415,7 @@
 #
 # IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
+CONFIG_NF_CONNTRACK_IPV6=m
 # CONFIG_IP6_NF_QUEUE is not set
 # CONFIG_IP6_NF_IPTABLES is not set
 
@@ -379,7 +442,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -404,6 +466,7 @@
 CONFIG_IEEE80211_SOFTMAC=m
 # CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
 CONFIG_WIRELESS_EXT=y
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -436,11 +499,13 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -495,6 +560,7 @@
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
+# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -527,14 +593,22 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -570,8 +644,10 @@
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -581,6 +657,7 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_TC86C001=m
 # CONFIG_IDE_ARM is not set
 # CONFIG_IDE_CHIPSETS is not set
 CONFIG_BLK_DEV_IDEDMA=y
@@ -593,6 +670,12 @@
 #
 CONFIG_RAID_ATTRS=m
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Old CD-ROM drivers (not SCSI, not IDE)
@@ -648,6 +731,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -702,7 +787,7 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_LAN_SAA9730 is not set
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -721,14 +806,18 @@
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -785,6 +874,7 @@
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -804,6 +894,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -826,6 +917,7 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
@@ -868,6 +960,7 @@
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_TXX9=y
 CONFIG_HAS_TXX9_SERIAL=y
+CONFIG_SERIAL_TXX9_NR_UARTS=6
 # CONFIG_SERIAL_TXX9_CONSOLE is not set
 # CONFIG_SERIAL_TXX9_STDSERIAL is not set
 # CONFIG_SERIAL_JSM is not set
@@ -890,10 +983,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -901,7 +990,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -926,17 +1014,14 @@
 # CONFIG_HWMON_VID is not set
 # CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -952,6 +1037,7 @@
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
@@ -971,6 +1057,7 @@
 CONFIG_FB_ATY_CT=y
 # CONFIG_FB_ATY_GENERIC_LCD is not set
 # CONFIG_FB_ATY_GX is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
@@ -1002,6 +1089,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -1014,8 +1107,8 @@
 # Miscellaneous USB options
 #
 # CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -1040,14 +1133,12 @@
 #
 # may also be needed; see USB_STORAGE Help for more information
 #
-# CONFIG_USB_STORAGE is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 CONFIG_USB_HIDDEV=y
@@ -1063,6 +1154,7 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -1076,6 +1168,7 @@
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 CONFIG_USB_MON=y
 
@@ -1093,18 +1186,20 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX 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_CY7C63 is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB DSL modem support
@@ -1161,6 +1256,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1170,6 +1273,7 @@
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=m
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1178,12 +1282,13 @@
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_REISERFS_FS_XATTR is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=m
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1194,6 +1299,7 @@
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -1218,11 +1324,13 @@
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -1234,7 +1342,6 @@
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
@@ -1273,7 +1380,6 @@
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1330,6 +1436,14 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1339,11 +1453,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1357,18 +1473,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1380,6 +1508,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1389,6 +1518,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1399,3 +1529,5 @@
 CONFIG_TEXTSEARCH_KMP=m
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index 496aa67..0417e86 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:19 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:09 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,10 +64,14 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_ARC=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_DMA_NONCOHERENT=y
@@ -78,10 +82,10 @@
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
 CONFIG_ARC32=y
 CONFIG_BOOT_ELF32=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+CONFIG_MIPS_L1_CACHE_SHIFT=4
 CONFIG_ARC_CONSOLE=y
 CONFIG_ARC_MEMORY=y
 CONFIG_ARC_PROMLIB=y
@@ -110,6 +114,7 @@
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_R4X00=y
 CONFIG_SYS_HAS_CPU_R5000=y
+CONFIG_SYS_HAS_CPU_R10000=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@@ -127,8 +132,8 @@
 CONFIG_BOARD_SCACHE=y
 CONFIG_R5000_CPU_SCACHE=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -146,6 +151,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -158,6 +164,7 @@
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -176,17 +183,22 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -194,12 +206,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -217,6 +229,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -263,6 +276,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -276,7 +297,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=m
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -297,10 +321,13 @@
 CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -313,11 +340,17 @@
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=y
 CONFIG_INET6_XFRM_TUNNEL=m
 CONFIG_INET6_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_TRANSPORT=m
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
 CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -329,18 +362,43 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
 # CONFIG_NETFILTER_XT_TARGET_CONNSECMARK is not set
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
@@ -358,60 +416,45 @@
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CONNTRACK_SECMARK=y
-CONFIG_IP_NF_CONNTRACK_EVENTS=y
-CONFIG_IP_NF_CONNTRACK_NETLINK=m
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_PPTP=m
-CONFIG_IP_NF_H323=m
-CONFIG_IP_NF_SIP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_MATCH_OWNER=m
 CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_NAT_PPTP=m
-CONFIG_IP_NF_NAT_H323=m
-CONFIG_IP_NF_NAT_SIP=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
 CONFIG_IP_NF_TARGET_TTL=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
@@ -422,6 +465,7 @@
 #
 # IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
+CONFIG_NF_CONNTRACK_IPV6=m
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_RT=m
@@ -431,6 +475,7 @@
 CONFIG_IP6_NF_MATCH_OWNER=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_MH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
@@ -493,7 +538,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -501,6 +545,7 @@
 # QoS and/or fair queueing
 #
 CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FIFO=y
 CONFIG_NET_SCH_CLK_JIFFIES=y
 # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
 # CONFIG_NET_SCH_CLK_CPU is not set
@@ -575,6 +620,7 @@
 CONFIG_IEEE80211_SOFTMAC=m
 # CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
 CONFIG_WIRELESS_EXT=y
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -606,10 +652,10 @@
 CONFIG_PARPORT_SERIAL=m
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
-CONFIG_PARPORT_NOT_PC=y
 # CONFIG_PARPORT_GSC is not set
 # CONFIG_PARPORT_AX88796 is not set
 CONFIG_PARPORT_1284=y
+CONFIG_PARPORT_NOT_PC=y
 
 #
 # Plug and Play support
@@ -621,7 +667,6 @@
 #
 CONFIG_BLK_DEV_FD=m
 CONFIG_PARIDE=m
-CONFIG_PARIDE_PARPORT=m
 
 #
 # Parallel IDE high-level drivers
@@ -664,6 +709,7 @@
 CONFIG_BLK_DEV_RAM=m
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -671,6 +717,12 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -680,6 +732,8 @@
 #
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -699,14 +753,17 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
 
 #
 # SCSI low-level drivers
@@ -720,14 +777,16 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+CONFIG_SCSI_AIC94XX=m
+# CONFIG_AIC94XX_DEBUG is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_ARCMSR is not set
 CONFIG_MEGARAID_NEWGEN=y
 CONFIG_MEGARAID_MM=m
 CONFIG_MEGARAID_MAILBOX=m
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
@@ -742,17 +801,19 @@
 # CONFIG_SCSI_IZIP_EPP16 is not set
 # CONFIG_SCSI_IZIP_SLOW_CTR is not set
 # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_SNI_53C710 is not set
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 CONFIG_SCSI_SYM53C8XX_MMIO=y
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PSI240I is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_DC395x is not set
@@ -760,6 +821,12 @@
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Old CD-ROM drivers (not SCSI, not IDE)
@@ -780,6 +847,7 @@
 CONFIG_MD_MULTIPATH=m
 CONFIG_MD_FAULTY=m
 CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
 # CONFIG_DM_CRYPT is not set
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
@@ -834,6 +902,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -868,6 +938,7 @@
 # CONFIG_SEEQ8005 is not set
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=y
+# CONFIG_PCNET32_NAPI is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_AC3200 is not set
@@ -888,7 +959,7 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_LAN_SAA9730 is not set
+# CONFIG_SC92031 is not set
 # CONFIG_NET_POCKET is not set
 
 #
@@ -908,14 +979,18 @@
 CONFIG_VIA_VELOCITY=m
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -956,6 +1031,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=m
 
 #
 # Userland interfaces
@@ -978,6 +1054,7 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
@@ -1051,10 +1128,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -1062,7 +1135,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -1101,14 +1173,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -1129,6 +1196,7 @@
 # CONFIG_VGACON_SOFT_SCROLLBACK is not set
 # CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -1136,6 +1204,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -1148,8 +1222,8 @@
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -1159,9 +1233,11 @@
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=m
 # CONFIG_USB_SL811_HCD is not set
@@ -1189,18 +1265,20 @@
 CONFIG_USB_STORAGE_SDDR55=y
 CONFIG_USB_STORAGE_JUMPSHOT=y
 # CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
 #
 CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_HIDINPUT_POWERBOOK is not set
 CONFIG_HID_FF=y
 CONFIG_HID_PID=y
 CONFIG_LOGITECH_FF=y
+# CONFIG_PANTHERLORD_FF is not set
 CONFIG_THRUSTMASTER_FF=y
+# CONFIG_ZEROPLUS_FF is not set
 CONFIG_USB_HIDDEV=y
 
 #
@@ -1220,6 +1298,7 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -1234,12 +1313,14 @@
 CONFIG_USB_KAWETH=m
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET_MII=m
 CONFIG_USB_USBNET=m
 CONFIG_USB_NET_AX8817X=m
 CONFIG_USB_NET_CDCETHER=m
 # CONFIG_USB_NET_GL620A is not set
 CONFIG_USB_NET_NET1080=m
 # CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_MCS7830 is not set
 # CONFIG_USB_NET_RNDIS_HOST is not set
 # CONFIG_USB_NET_CDC_SUBSET is not set
 CONFIG_USB_NET_ZAURUS=m
@@ -1255,8 +1336,8 @@
 #
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
 CONFIG_USB_SERIAL_AIRPRIME=m
-CONFIG_USB_SERIAL_ANYDATA=m
 # CONFIG_USB_SERIAL_ARK3116 is not set
 CONFIG_USB_SERIAL_BELKIN=m
 CONFIG_USB_SERIAL_WHITEHEAT=m
@@ -1290,16 +1371,20 @@
 CONFIG_USB_SERIAL_KLSI=m
 CONFIG_USB_SERIAL_KOBIL_SCT=m
 CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 CONFIG_USB_SERIAL_HP4X=m
 CONFIG_USB_SERIAL_SAFE=m
 CONFIG_USB_SERIAL_SAFE_PADDED=y
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
 # CONFIG_USB_SERIAL_TI is not set
 CONFIG_USB_SERIAL_CYBERJACK=m
 CONFIG_USB_SERIAL_XIRCOM=m
 # CONFIG_USB_SERIAL_OPTION is not set
 CONFIG_USB_SERIAL_OMNINET=m
+# CONFIG_USB_SERIAL_DEBUG is not set
 CONFIG_USB_EZUSB=y
 
 #
@@ -1307,20 +1392,22 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 CONFIG_USB_AUERSWALD=m
 CONFIG_USB_RIO500=m
 CONFIG_USB_LEGOTOWER=m
 CONFIG_USB_LCD=m
 CONFIG_USB_LED=m
-# CONFIG_USB_CY7C63 is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 CONFIG_USB_CYTHERM=m
-CONFIG_USB_PHIDGETKIT=m
-CONFIG_USB_PHIDGETSERVO=m
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 CONFIG_USB_SISUSBVGA=m
 # CONFIG_USB_SISUSBVGA_CON is not set
 CONFIG_USB_LD=m
+# CONFIG_USB_TRANCEVIBRATOR is not set
 CONFIG_USB_TEST=m
 
 #
@@ -1378,6 +1465,15 @@
 #
 
 #
+# Auxiliary Display support
+#
+# CONFIG_KS0108 is not set
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=m
@@ -1387,6 +1483,7 @@
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1403,6 +1500,7 @@
 CONFIG_XFS_SECURITY=y
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=m
 CONFIG_ROMFS_FS=m
@@ -1414,6 +1512,7 @@
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -1421,7 +1520,6 @@
 CONFIG_ISO9660_FS=m
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
-CONFIG_ZISOFS_FS=m
 CONFIG_UDF_FS=m
 CONFIG_UDF_NLS=y
 
@@ -1442,11 +1540,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -1454,6 +1554,7 @@
 CONFIG_ADFS_FS=m
 # CONFIG_ADFS_FS_RW is not set
 CONFIG_AFFS_FS=m
+# CONFIG_ECRYPT_FS is not set
 CONFIG_HFS_FS=m
 # CONFIG_HFSPLUS_FS is not set
 CONFIG_BEFS_FS=m
@@ -1579,6 +1680,14 @@
 CONFIG_NLS_UTF8=m
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1588,11 +1697,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1607,18 +1718,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1630,6 +1753,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1639,6 +1763,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -1650,3 +1775,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index e33c172..533df6f 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:19 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:09 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -81,10 +81,14 @@
 # CONFIG_SIBYTE_SB1250_PROF is not set
 # CONFIG_SIBYTE_TBPROF is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_COHERENT=y
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -117,6 +121,7 @@
 # CONFIG_CPU_RM9000 is not set
 CONFIG_CPU_SB1=y
 CONFIG_SYS_HAS_CPU_SB1=y
+CONFIG_WEAK_ORDERING=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@@ -134,8 +139,8 @@
 # CONFIG_SIBYTE_DMA_PAGEOPS is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_SB1_PASS_1_WORKAROUNDS=y
 CONFIG_CPU_HAS_LLSC=y
@@ -155,8 +160,10 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
 CONFIG_SMP=y
 CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_NR_CPUS_DEFAULT_2=y
 CONFIG_NR_CPUS=2
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
@@ -171,6 +178,7 @@
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_PREEMPT_BKL=y
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -189,16 +197,22 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_CPUSETS=y
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -206,12 +220,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -230,6 +244,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
@@ -270,11 +285,20 @@
 # CONFIG_BUILD_ELF64 is not set
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
 CONFIG_MIPS32_O32=y
 # CONFIG_MIPS32_N32 is not set
 CONFIG_BINFMT_ELF32=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -288,7 +312,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -308,10 +335,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -341,7 +371,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -410,6 +439,7 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=9220
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -417,9 +447,16 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -449,6 +486,12 @@
 #
 CONFIG_RAID_ATTRS=m
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -499,6 +542,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -535,14 +580,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -604,6 +652,7 @@
 # CONFIG_DIGIEPCA is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
+CONFIG_MOXA_SMARTIO_NEW=m
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_SYNCLINK_GT is not set
@@ -643,10 +692,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -654,7 +699,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -679,14 +723,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -698,6 +737,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -767,6 +807,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -775,11 +823,13 @@
 CONFIG_EXT2_FS_SECURITY=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -809,17 +859,19 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -850,7 +902,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -868,6 +919,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -877,11 +936,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=15
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 # CONFIG_SB1XXX_CORELIS is not set
@@ -897,18 +958,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -920,6 +993,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -929,6 +1003,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=m
 CONFIG_CRC32=y
@@ -936,3 +1011,5 @@
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
index 83fb932..38816fe 100644
--- a/arch/mips/configs/sead_defconfig
+++ b/arch/mips/configs/sead_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:20 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:10 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,10 +64,14 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
@@ -120,8 +124,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -139,6 +143,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -151,6 +156,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -169,13 +175,18 @@
 CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_UTS_NS is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 # CONFIG_HOTPLUG is not set
@@ -183,12 +194,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -201,6 +212,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -226,7 +238,6 @@
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
 
 #
 # PCI Hotplug Support
@@ -240,6 +251,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 # CONFIG_NET is not set
@@ -253,7 +272,6 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -283,10 +301,15 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=18432
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 
 #
+# Misc devices
+#
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -296,6 +319,12 @@
 #
 CONFIG_RAID_ATTRS=y
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -373,17 +402,12 @@
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -399,6 +423,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -407,14 +432,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -425,6 +445,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -492,16 +513,26 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -530,6 +561,7 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
@@ -585,12 +617,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
-# CONFIG_UNWIND_INFO is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -606,10 +639,6 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
@@ -617,3 +646,5 @@
 # CONFIG_CRC32 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
index e9d4eae..c2f7c8c 100644
--- a/arch/mips/configs/tb0226_defconfig
+++ b/arch/mips/configs/tb0226_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:20 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:11 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 CONFIG_MACH_VR41XX=y
 # CONFIG_PMC_YOSEMITE is not set
@@ -72,12 +72,15 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 CONFIG_PCI_VR41XX=y
-# CONFIG_VRC4173 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
@@ -110,6 +113,7 @@
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_VR41XX=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
@@ -123,8 +127,8 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -139,6 +143,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -151,6 +156,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -169,15 +175,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -185,12 +196,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -208,6 +219,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -250,6 +262,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -263,6 +283,8 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -290,10 +312,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -323,7 +348,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -340,6 +364,7 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_IEEE80211 is not set
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -388,11 +413,18 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -402,6 +434,8 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -420,14 +454,17 @@
 CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
 
 #
 # SCSI low-level drivers
@@ -440,26 +477,35 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+CONFIG_SCSI_AIC94XX=m
+# CONFIG_AIC94XX_DEBUG is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -513,6 +559,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -549,7 +597,7 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_LAN_SAA9730 is not set
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -568,14 +616,18 @@
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -615,6 +667,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -682,10 +735,6 @@
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_TANBAC_TB0219 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 CONFIG_GPIO_VR41XX=y
 # CONFIG_RAW_DRIVER is not set
@@ -694,7 +743,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -719,14 +767,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -745,6 +788,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -752,6 +796,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -764,8 +814,8 @@
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -775,9 +825,11 @@
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
@@ -805,6 +857,7 @@
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -829,6 +882,7 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -843,6 +897,7 @@
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 # CONFIG_USB_MON is not set
 
@@ -860,19 +915,21 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX 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_CY7C63 is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -918,6 +975,7 @@
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
 CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
 
 #
 # RTC interfaces
@@ -951,16 +1009,26 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=m
@@ -971,6 +1039,7 @@
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -990,11 +1059,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -1036,7 +1107,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1054,6 +1124,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1063,11 +1141,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="mem=32M console=ttyVR0,115200"
 
@@ -1080,7 +1160,44 @@
 #
 # Cryptographic options
 #
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
+# CONFIG_CRYPTO_TEST is not set
 
 #
 # Hardware crypto devices
@@ -1092,6 +1209,9 @@
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 # CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig
index c19597f..33b7880 100644
--- a/arch/mips/configs/tb0229_defconfig
+++ b/arch/mips/configs/tb0229_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:20 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:12 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 CONFIG_MACH_VR41XX=y
 # CONFIG_PMC_YOSEMITE is not set
@@ -72,12 +72,15 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 CONFIG_PCI_VR41XX=y
-# CONFIG_VRC4173 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
@@ -110,6 +113,7 @@
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_VR41XX=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
@@ -123,8 +127,8 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -139,6 +143,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -151,6 +156,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -169,15 +175,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -185,12 +196,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -208,6 +219,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -250,6 +262,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -263,6 +283,8 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -291,10 +313,13 @@
 CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -324,7 +349,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -341,6 +365,7 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_IEEE80211 is not set
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -389,11 +414,18 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -403,6 +435,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -453,6 +491,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -489,14 +529,17 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -535,6 +578,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -602,10 +646,6 @@
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 CONFIG_TANBAC_TB0219=y
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 CONFIG_GPIO_VR41XX=y
 # CONFIG_RAW_DRIVER is not set
@@ -614,7 +654,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -630,6 +669,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -638,14 +678,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -664,6 +699,7 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -671,6 +707,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -683,8 +725,8 @@
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -694,9 +736,11 @@
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
@@ -714,7 +758,6 @@
 #
 # may also be needed; see USB_STORAGE Help for more information
 #
-# CONFIG_USB_STORAGE is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -739,6 +782,7 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -752,6 +796,7 @@
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 CONFIG_USB_MON=y
 
@@ -769,19 +814,21 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX 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_CY7C63 is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -827,6 +874,7 @@
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
 CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
 
 #
 # RTC interfaces
@@ -860,16 +908,26 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=m
@@ -880,6 +938,7 @@
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -899,11 +958,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -945,7 +1006,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -963,6 +1023,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -972,11 +1040,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
 
@@ -989,7 +1059,44 @@
 #
 # Cryptographic options
 #
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
+# CONFIG_CRYPTO_TEST is not set
 
 #
 # Hardware crypto devices
@@ -998,9 +1105,13 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
index 97d94f9..d180586 100644
--- a/arch/mips/configs/tb0287_defconfig
+++ b/arch/mips/configs/tb0287_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc2
-# Wed Oct 18 12:57:11 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:13 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -40,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 CONFIG_MACH_VR41XX=y
 # CONFIG_PMC_YOSEMITE is not set
@@ -71,11 +73,14 @@
 # CONFIG_ZAO_CAPCELLA is not set
 CONFIG_PCI_VR41XX=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
@@ -108,6 +113,7 @@
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_VR41XX=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
@@ -137,6 +143,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -149,6 +156,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -168,14 +176,15 @@
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
@@ -233,7 +242,6 @@
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
-# CONFIG_PCI_MULTITHREAD_PROBE is not set
 CONFIG_MMU=y
 
 #
@@ -252,6 +260,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -266,6 +282,7 @@
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -315,6 +332,7 @@
 # CONFIG_DEFAULT_WESTWOOD is not set
 # CONFIG_DEFAULT_RENO is not set
 CONFIG_DEFAULT_TCP_CONG="bic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -414,6 +432,12 @@
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -423,6 +447,7 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
 # CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
@@ -442,6 +467,7 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
 # SCSI Transports
@@ -486,11 +512,13 @@
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
 
 #
 # Serial ATA (prod) and Parallel ATA (experimental) drivers
 #
 CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
 # CONFIG_SATA_AHCI is not set
 # CONFIG_SATA_SVW is not set
 # CONFIG_ATA_PIIX is not set
@@ -506,6 +534,7 @@
 # CONFIG_SATA_ULI is not set
 # CONFIG_SATA_VIA is not set
 # CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
 # CONFIG_PATA_ALI is not set
 # CONFIG_PATA_AMD is not set
 # CONFIG_PATA_ARTOP is not set
@@ -521,8 +550,10 @@
 # CONFIG_PATA_HPT3X2N is not set
 # CONFIG_PATA_HPT3X3 is not set
 # CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
 # CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
 # CONFIG_PATA_OLDPIIX is not set
 # CONFIG_PATA_NETCELL is not set
@@ -539,6 +570,7 @@
 # CONFIG_PATA_SIS is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -562,10 +594,8 @@
 # Subsystem Options
 #
 # CONFIG_IEEE1394_VERBOSEDEBUG is not set
-# CONFIG_IEEE1394_OUI_DB is not set
 CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
 CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
-# CONFIG_IEEE1394_EXPORT_FULL_API is not set
 
 #
 # Device Drivers
@@ -650,9 +680,11 @@
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -760,10 +792,6 @@
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_TANBAC_TB0219 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 CONFIG_GPIO_VR41XX=y
 # CONFIG_RAW_DRIVER is not set
@@ -787,6 +815,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -795,11 +824,6 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-# CONFIG_TIFM_CORE is not set
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -818,6 +842,7 @@
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
@@ -834,6 +859,7 @@
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
@@ -863,6 +889,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -875,8 +907,8 @@
 # Miscellaneous USB options
 #
 # CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -886,9 +918,11 @@
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
@@ -923,7 +957,6 @@
 # USB Input Devices
 #
 CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 # CONFIG_USB_HIDDEV is not set
@@ -945,7 +978,7 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -960,6 +993,7 @@
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 CONFIG_USB_MON=y
 
@@ -991,6 +1025,7 @@
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB DSL modem support
@@ -1047,6 +1082,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1105,7 +1148,7 @@
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -1159,6 +1202,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1171,10 +1222,10 @@
 CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
 
@@ -1187,14 +1238,59 @@
 #
 # Cryptographic options
 #
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
index 553734a..570f0c1 100644
--- a/arch/mips/configs/workpad_defconfig
+++ b/arch/mips/configs/workpad_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc2
-# Tue Jul 25 23:13:04 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:13 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 CONFIG_MACH_VR41XX=y
 # CONFIG_PMC_YOSEMITE is not set
@@ -70,10 +70,14 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 # CONFIG_CPU_BIG_ENDIAN is not set
@@ -106,6 +110,7 @@
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_VR41XX=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
@@ -119,8 +124,8 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -135,6 +140,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -147,6 +153,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -165,16 +172,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -182,12 +193,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -205,6 +216,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -257,6 +269,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -270,7 +290,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -288,10 +311,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -321,7 +347,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -387,9 +412,14 @@
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -419,6 +449,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Old CD-ROM drivers (not SCSI, not IDE)
@@ -472,6 +508,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -575,6 +613,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -641,10 +680,6 @@
 # CONFIG_R3964 is not set
 
 #
-# Ftape, the floppy tape device driver
-#
-
-#
 # PCMCIA character devices
 #
 # CONFIG_SYNCLINK_CS is not set
@@ -657,7 +692,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -682,14 +716,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -708,6 +737,7 @@
 # CONFIG_VGA_CONSOLE is not set
 # CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -715,6 +745,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
@@ -775,6 +811,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -783,11 +827,13 @@
 CONFIG_EXT2_FS_SECURITY=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -798,6 +844,7 @@
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -817,11 +864,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -875,6 +924,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -884,11 +941,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x170,0x376,49 mem=16M"
 
@@ -901,7 +960,44 @@
 #
 # Cryptographic options
 #
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
+# CONFIG_CRYPTO_TEST is not set
 
 #
 # Hardware crypto devices
@@ -910,8 +1006,13 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig
index d3dfb70..08f3190 100644
--- a/arch/mips/configs/wrppmc_defconfig
+++ b/arch/mips/configs/wrppmc_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:21 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:14 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,10 +64,14 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_CPU_BIG_ENDIAN=y
@@ -124,8 +128,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -143,6 +147,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -155,6 +160,7 @@
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -173,16 +179,22 @@
 CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_HOTPLUG=y
@@ -190,12 +202,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 # CONFIG_EPOLL is not set
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -213,6 +225,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -258,6 +271,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -271,6 +292,8 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -294,10 +317,13 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -327,7 +353,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -390,11 +415,18 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -404,6 +436,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -454,6 +492,8 @@
 # CONFIG_CICADA_PHY is not set
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -490,7 +530,7 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_LAN_SAA9730 is not set
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -509,14 +549,18 @@
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -602,10 +646,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -613,7 +653,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -629,6 +668,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -637,17 +677,14 @@
 # CONFIG_HWMON_VID is not set
 # CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -659,6 +696,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -728,14 +766,24 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -746,6 +794,7 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -765,11 +814,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -806,7 +857,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -824,6 +874,14 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -833,11 +891,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="console=ttyS0,115200n8"
 
@@ -850,7 +910,44 @@
 #
 # Cryptographic options
 #
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
+# CONFIG_CRYPTO_TEST is not set
 
 #
 # Hardware crypto devices
@@ -859,8 +956,13 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=y
 CONFIG_CRC16=y
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index b9f74d6..aa69fee 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:21 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:28:15 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 CONFIG_PMC_YOSEMITE=y
@@ -65,10 +65,14 @@
 # CONFIG_TOSHIBA_RBTX4938 is not set
 # CONFIG_HYPERTRANSPORT is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_DMA_COHERENT=y
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -102,6 +106,7 @@
 CONFIG_CPU_RM9000=y
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_RM9000=y
+CONFIG_WEAK_ORDERING=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@@ -118,8 +123,8 @@
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -136,6 +141,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 CONFIG_SMP=y
 CONFIG_SYS_SUPPORTS_SMP=y
 CONFIG_NR_CPUS=2
@@ -170,15 +176,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_CPUSETS is not set
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -187,12 +198,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -210,6 +221,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -252,6 +264,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -281,13 +301,15 @@
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_IPV6=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
@@ -298,6 +320,8 @@
 CONFIG_INET6_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_TRANSPORT=m
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_IPV6_SIT=m
 CONFIG_IPV6_TUNNEL=m
 CONFIG_NETWORK_SECMARK=y
 # CONFIG_NETFILTER is not set
@@ -336,6 +360,7 @@
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -374,6 +399,11 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=m
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -383,6 +413,12 @@
 #
 CONFIG_RAID_ATTRS=m
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -433,6 +469,8 @@
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -463,18 +501,22 @@
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_TITAN_GE=y
+CONFIG_QLA3XXX=m
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+CONFIG_NETXEN_NIC=m
 
 #
 # Token Ring devices
@@ -559,10 +601,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -593,14 +631,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -612,6 +645,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -680,14 +714,23 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -697,6 +740,7 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -716,8 +760,10 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 
@@ -737,6 +783,7 @@
 #
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
+# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
@@ -744,7 +791,6 @@
 CONFIG_SUNRPC=y
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 
@@ -764,25 +810,31 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_HIGHMEM is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
@@ -802,6 +854,10 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
@@ -811,9 +867,14 @@
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -825,6 +886,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -834,6 +896,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=m
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=m
 CONFIG_CRC32=m
@@ -841,3 +904,5 @@
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index f9812d1..6c2a233 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:10 2006
+# Linux kernel version: 2.6.20
+# Sun Feb 18 21:27:34 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_MIPS_BOSPORUS is not set
 # CONFIG_MIPS_PB1000 is not set
@@ -25,8 +26,6 @@
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -42,6 +41,7 @@
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
@@ -64,13 +64,18 @@
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
 CONFIG_ARC=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
@@ -123,8 +128,8 @@
 CONFIG_BOARD_SCACHE=y
 CONFIG_IP22_CPU_SCACHE=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -141,6 +146,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -153,6 +159,7 @@
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -171,16 +178,21 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 # CONFIG_HOTPLUG is not set
@@ -188,12 +200,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -211,6 +223,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -238,7 +251,6 @@
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
 
 #
 # PCI Hotplug Support
@@ -252,6 +264,14 @@
 CONFIG_TRAD_SIGNALS=y
 
 #
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+
+#
 # Networking
 #
 CONFIG_NET=y
@@ -265,7 +285,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -286,10 +309,13 @@
 CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
 
 #
 # IP: Virtual Server Configuration
@@ -331,11 +357,17 @@
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=y
 CONFIG_INET6_XFRM_TUNNEL=m
 CONFIG_INET6_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_TRANSPORT=m
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
 CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -346,19 +378,43 @@
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK_SUPPORT=y
+# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
 CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
@@ -375,60 +431,45 @@
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_CT_ACCT=y
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CONNTRACK_SECMARK=y
-CONFIG_IP_NF_CONNTRACK_EVENTS=y
-CONFIG_IP_NF_CONNTRACK_NETLINK=m
-# CONFIG_IP_NF_CT_PROTO_SCTP is not set
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_PPTP=m
-CONFIG_IP_NF_H323=m
-CONFIG_IP_NF_SIP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_MATCH_OWNER=m
 CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_NAT_PPTP=m
-CONFIG_IP_NF_NAT_H323=m
-CONFIG_IP_NF_NAT_SIP=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
 CONFIG_IP_NF_TARGET_TTL=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
@@ -439,6 +480,7 @@
 #
 # IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
+CONFIG_NF_CONNTRACK_IPV6=m
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_RT=m
@@ -448,6 +490,7 @@
 CONFIG_IP6_NF_MATCH_OWNER=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_MH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
@@ -484,7 +527,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-CONFIG_NET_DIVERT=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -492,6 +534,7 @@
 # QoS and/or fair queueing
 #
 CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FIFO=y
 # CONFIG_NET_SCH_CLK_JIFFIES is not set
 CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
 # CONFIG_NET_SCH_CLK_CPU is not set
@@ -546,6 +589,7 @@
 CONFIG_IEEE80211_SOFTMAC=m
 # CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
 CONFIG_WIRELESS_EXT=y
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -556,7 +600,6 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -592,6 +635,10 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -601,6 +648,8 @@
 #
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -620,24 +669,30 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=m
 # CONFIG_SCSI_FC_ATTRS is not set
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
 CONFIG_ISCSI_TCP=m
 CONFIG_SGIWD93_SCSI=y
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
@@ -679,6 +734,8 @@
 CONFIG_CICADA_PHY=m
 # CONFIG_VITESSE_PHY is not set
 # CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -730,6 +787,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -752,6 +810,7 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=m
 CONFIG_MOUSE_SERIAL=m
@@ -815,10 +874,6 @@
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 CONFIG_RAW_DRIVER=m
 CONFIG_MAX_RAW_DEVS=256
 
@@ -826,7 +881,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -851,14 +905,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -887,6 +936,7 @@
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_SGI_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -894,6 +944,12 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
@@ -954,6 +1010,14 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=m
@@ -963,6 +1027,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -974,6 +1039,7 @@
 CONFIG_XFS_SECURITY=y
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=m
 # CONFIG_ROMFS_FS is not set
@@ -987,6 +1053,7 @@
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -994,7 +1061,6 @@
 CONFIG_ISO9660_FS=m
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
-CONFIG_ZISOFS_FS=m
 CONFIG_UDF_FS=m
 CONFIG_UDF_NLS=y
 
@@ -1013,17 +1079,20 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -1142,6 +1211,14 @@
 CONFIG_NLS_UTF8=m
 
 #
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1151,11 +1228,13 @@
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1170,18 +1249,30 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1193,6 +1284,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1202,6 +1294,7 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=m
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=m
 CONFIG_CRC32=m
@@ -1213,3 +1306,5 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 1bf2c84..8faf1b4 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -53,9 +53,9 @@
 obj-$(CONFIG_32BIT)		+= scall32-o32.o
 obj-$(CONFIG_64BIT)		+= scall64-64.o
 obj-$(CONFIG_BINFMT_IRIX)	+= binfmt_irix.o
-obj-$(CONFIG_MIPS32_COMPAT)	+= linux32.o signal32.o
+obj-$(CONFIG_MIPS32_COMPAT)	+= linux32.o ptrace32.o signal32.o
 obj-$(CONFIG_MIPS32_N32)	+= binfmt_elfn32.o scall64-n32.o signal_n32.o
-obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o ptrace32.o
+obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o
 
 obj-$(CONFIG_KGDB)		+= gdb-low.o gdb-stub.o
 obj-$(CONFIG_PROC_FS)		+= proc.o
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index f59ef27..ab755ea 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -16,6 +16,7 @@
 #include <linux/ptrace.h>
 #include <linux/stddef.h>
 
+#include <asm/bugs.h>
 #include <asm/cpu.h>
 #include <asm/fpu.h>
 #include <asm/mipsregs.h>
@@ -97,7 +98,7 @@
 
 static int __initdata nowait = 0;
 
-int __init wait_disable(char *s)
+static int __init wait_disable(char *s)
 {
 	nowait = 1;
 
diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c
index e0ad754..8f42fa8 100644
--- a/arch/mips/kernel/machine_kexec.c
+++ b/arch/mips/kernel/machine_kexec.c
@@ -13,8 +13,8 @@
 #include <asm/cacheflush.h>
 #include <asm/page.h>
 
-const extern unsigned char relocate_new_kernel[];
-const extern unsigned int relocate_new_kernel_size;
+extern const unsigned char relocate_new_kernel[];
+extern const unsigned int relocate_new_kernel_size;
 
 extern unsigned long kexec_start_address;
 extern unsigned long kexec_indirection_page;
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 04e5b38..a669089 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -26,7 +26,6 @@
 #include <linux/completion.h>
 #include <linux/kallsyms.h>
 
-#include <asm/abi.h>
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
 #include <asm/dsp.h>
@@ -66,38 +65,6 @@
 	}
 }
 
-/*
- * Native o32 and N64 ABI without DSP ASE
- */
-struct mips_abi mips_abi = {
-	.do_signal	= do_signal,
-#ifdef CONFIG_TRAD_SIGNALS
-	.setup_frame	= setup_frame,
-#endif
-	.setup_rt_frame	= setup_rt_frame
-};
-
-#ifdef CONFIG_MIPS32_O32
-/*
- * o32 compatibility on 64-bit kernels, without DSP ASE
- */
-struct mips_abi mips_abi_32 = {
-	.do_signal	= do_signal32,
-	.setup_frame	= setup_frame_32,
-	.setup_rt_frame	= setup_rt_frame_32
-};
-#endif /* CONFIG_MIPS32_O32 */
-
-#ifdef CONFIG_MIPS32_N32
-/*
- * N32 on 64-bit kernels, without DSP ASE
- */
-struct mips_abi mips_abi_n32 = {
-	.do_signal	= do_signal,
-	.setup_rt_frame	= setup_rt_frame_n32
-};
-#endif /* CONFIG_MIPS32_N32 */
-
 asmlinkage void ret_from_fork(void);
 
 void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
@@ -246,7 +213,7 @@
 /*
  * Create a kernel thread
  */
-ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
+static ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
 {
 	do_exit(fn(arg));
 }
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 394540f..11ab222 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -543,7 +543,7 @@
 #endif
 }
 
-int __init fpu_disable(char *s)
+static int __init fpu_disable(char *s)
 {
 	int i;
 
@@ -555,7 +555,7 @@
 
 __setup("nofpu", fpu_disable);
 
-int __init dsp_disable(char *s)
+static int __init dsp_disable(char *s)
 {
 	cpu_data[0].ases &= ~MIPS_ASE_DSP;
 
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index b2e9ab1..adbfb95 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -398,7 +398,7 @@
 }
 
 #ifdef CONFIG_TRAD_SIGNALS
-int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
 	int signr, sigset_t *set)
 {
 	struct sigframe __user *frame;
@@ -443,7 +443,7 @@
 }
 #endif
 
-int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
 	int signr, sigset_t *set, siginfo_t *info)
 {
 	struct rt_sigframe __user *frame;
@@ -501,6 +501,14 @@
 	return -EFAULT;
 }
 
+struct mips_abi mips_abi = {
+#ifdef CONFIG_TRAD_SIGNALS
+	.setup_frame	= setup_frame,
+#endif
+	.setup_rt_frame	= setup_rt_frame,
+	.restart	= __NR_restart_syscall
+};
+
 static int handle_signal(unsigned long sig, siginfo_t *info,
 	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
 {
@@ -539,7 +547,7 @@
 	return ret;
 }
 
-void do_signal(struct pt_regs *regs)
+static void do_signal(struct pt_regs *regs)
 {
 	struct k_sigaction ka;
 	sigset_t *oldset;
@@ -589,7 +597,7 @@
 			regs->cp0_epc -= 8;
 		}
 		if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
-			regs->regs[2] = __NR_restart_syscall;
+			regs->regs[2] = current->thread.abi->restart;
 			regs->regs[7] = regs->regs[26];
 			regs->cp0_epc -= 4;
 		}
@@ -615,5 +623,5 @@
 {
 	/* deal with pending signal delivery */
 	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
-		current->thread.abi->do_signal(regs);
+		do_signal(regs);
 }
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index c28cb21..02062fc 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -104,7 +104,7 @@
  */
 #define __NR_O32_sigreturn		4119
 #define __NR_O32_rt_sigreturn		4193
-#define __NR_O32_restart_syscall	4253
+#define __NR_O32_restart_syscall        4253
 
 /* 32-bit compatibility types */
 
@@ -150,7 +150,7 @@
 	u32 sf_ass[4];		/* argument save space for o32 */
 	u32 sf_code[2];		/* signal trampoline */
 	struct sigcontext32 sf_sc;
-	sigset_t sf_mask;
+	compat_sigset_t sf_mask;
 };
 
 struct rt_sigframe32 {
@@ -166,7 +166,7 @@
 	u32 sf_ass[4];			/* argument save space for o32 */
 	u32 sf_pad[2];
 	struct sigcontext32 sf_sc;	/* hw context */
-	sigset_t sf_mask;
+	compat_sigset_t sf_mask;
 	u32 sf_code[8] ____cacheline_aligned;	/* signal trampoline */
 };
 
@@ -598,7 +598,7 @@
 	force_sig(SIGSEGV, current);
 }
 
-int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
+static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
 	int signr, sigset_t *set)
 {
 	struct sigframe32 __user *frame;
@@ -644,7 +644,7 @@
 	return -EFAULT;
 }
 
-int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
+static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
 	int signr, sigset_t *set, siginfo_t *info)
 {
 	struct rt_sigframe32 __user *frame;
@@ -704,110 +704,14 @@
 	return -EFAULT;
 }
 
-static inline int handle_signal(unsigned long sig, siginfo_t *info,
-	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
-{
-	int ret;
-
-	switch (regs->regs[0]) {
-	case ERESTART_RESTARTBLOCK:
-	case ERESTARTNOHAND:
-		regs->regs[2] = EINTR;
-		break;
-	case ERESTARTSYS:
-		if (!(ka->sa.sa_flags & SA_RESTART)) {
-			regs->regs[2] = EINTR;
-			break;
-		}
-	/* fallthrough */
-	case ERESTARTNOINTR:		/* Userland will reload $v0.  */
-		regs->regs[7] = regs->regs[26];
-		regs->cp0_epc -= 8;
-	}
-
-	regs->regs[0] = 0;		/* Don't deal with this again.  */
-
-	if (ka->sa.sa_flags & SA_SIGINFO)
-		ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
-	else
-		ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
-
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked,sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	return ret;
-}
-
-void do_signal32(struct pt_regs *regs)
-{
-	struct k_sigaction ka;
-	sigset_t *oldset;
-	siginfo_t info;
-	int signr;
-
-	/*
-	 * We want the common case to go fast, which is why we may in certain
-	 * cases get here from kernel mode. Just return without doing anything
-	 * if so.
-	 */
-	if (!user_mode(regs))
-		return;
-
-	if (test_thread_flag(TIF_RESTORE_SIGMASK))
-		oldset = &current->saved_sigmask;
-	else
-		oldset = &current->blocked;
-
-	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-	if (signr > 0) {
-		/* Whee! Actually deliver the signal. */
-		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
-			/*
-			* A signal was successfully delivered; the saved
-			* sigmask will have been stored in the signal frame,
-			* and will be restored by sigreturn, so we can simply
-			* clear the TIF_RESTORE_SIGMASK flag.
-			*/
-			if (test_thread_flag(TIF_RESTORE_SIGMASK))
-				clear_thread_flag(TIF_RESTORE_SIGMASK);
-		}
-
-		return;
-	}
-
-	/*
-	 * Who's code doesn't conform to the restartable syscall convention
-	 * dies here!!!  The li instruction, a single machine instruction,
-	 * must directly be followed by the syscall instruction.
-	 */
-	if (regs->regs[0]) {
-		if (regs->regs[2] == ERESTARTNOHAND ||
-		    regs->regs[2] == ERESTARTSYS ||
-		    regs->regs[2] == ERESTARTNOINTR) {
-			regs->regs[7] = regs->regs[26];
-			regs->cp0_epc -= 8;
-		}
-		if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
-			regs->regs[2] = __NR_O32_restart_syscall;
-			regs->regs[7] = regs->regs[26];
-			regs->cp0_epc -= 4;
-		}
-		regs->regs[0] = 0;	/* Don't deal with this again.  */
-	}
-
-	/*
-	* If there's no signal to deliver, we just put the saved sigmask
-	* back
-	*/
-	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-		clear_thread_flag(TIF_RESTORE_SIGMASK);
-		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
-	}
-}
+/*
+ * o32 compatibility on 64-bit kernels, without DSP ASE
+ */
+struct mips_abi mips_abi_32 = {
+	.setup_frame	= setup_frame_32,
+	.setup_rt_frame	= setup_rt_frame_32,
+	.restart	= __NR_O32_restart_syscall
+};
 
 asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
 				  struct sigaction32 __user *oact,
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 7ca2a07..ecf1f7e 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -29,6 +29,7 @@
 #include <linux/compat.h>
 #include <linux/bitops.h>
 
+#include <asm/abi.h>
 #include <asm/asm.h>
 #include <asm/cacheflush.h>
 #include <asm/compat-signal.h>
@@ -169,7 +170,7 @@
 	force_sig(SIGSEGV, current);
 }
 
-int setup_rt_frame_n32(struct k_sigaction * ka,
+static int setup_rt_frame_n32(struct k_sigaction * ka,
 	struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
 {
 	struct rt_sigframe_n32 __user *frame;
@@ -228,3 +229,8 @@
 	force_sigsegv(signr, current);
 	return -EFAULT;
 }
+
+struct mips_abi mips_abi_n32 = {
+	.setup_rt_frame	= setup_rt_frame_n32,
+	.restart	= __NR_N32_restart_syscall
+};
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 2a932ca..f663c63 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -340,13 +340,9 @@
 extern const struct exception_table_entry __start___dbe_table[];
 extern const struct exception_table_entry __stop___dbe_table[];
 
-void __declare_dbe_table(void)
-{
-	__asm__ __volatile__(
-	".section\t__dbe_table,\"a\"\n\t"
-	".previous"
-	);
-}
+__asm__(
+"	.section	__dbe_table, \"a\"\n"
+"	.previous			\n");
 
 /* Given an address, look for it in the exception tables. */
 static const struct exception_table_entry *search_dbe_tables(unsigned long addr)
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 5ad501b..2453ea2 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -2,10 +2,11 @@
 # Makefile for MIPS-specific library files..
 #
 
-lib-y	+= csum_partial.o memcpy.o memset.o promlib.o \
+lib-y	+= csum_partial.o memcpy.o memcpy-inatomic.o memset.o promlib.o \
 	   strlen_user.o strncpy_user.o strnlen_user.o uncached.o
 
-obj-y	+= iomap.o
+obj-y			+= iomap.o
+obj-$(CONFIG_PCI)	+= iomap-pci.o
 
 # libgcc-style stuff needed in the kernel
 lib-y += ashldi3.o ashrdi3.o lshrdi3.o
diff --git a/arch/mips/lib/iomap-pci.c b/arch/mips/lib/iomap-pci.c
new file mode 100644
index 0000000..c11b249
--- /dev/null
+++ b/arch/mips/lib/iomap-pci.c
@@ -0,0 +1,74 @@
+/*
+ * Implement the default iomap interfaces
+ *
+ * (C) Copyright 2004 Linus Torvalds
+ * (C) Copyright 2006 Ralf Baechle <ralf@linux-mips.org>
+ * (C) Copyright 2007 MIPS Technologies, Inc.
+ *     written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <asm/io.h>
+
+static void __iomem *ioport_map_pci(struct pci_dev *dev,
+                                     unsigned long port, unsigned int nr)
+{
+	struct pci_controller *ctrl = dev->bus->sysdata;
+	unsigned long base = ctrl->io_map_base;
+
+	/* This will eventually become a BUG_ON but for now be gentle */
+	if (unlikely(!ctrl->io_map_base)) {
+		struct pci_bus *bus = dev->bus;
+		char name[8];
+
+		while (bus->parent)
+			bus = bus->parent;
+
+		ctrl->io_map_base = base = mips_io_port_base;
+
+		sprintf(name, "%04x:%02x", pci_domain_nr(bus), bus->number);
+		printk(KERN_WARNING "io_map_base of root PCI bus %s unset.  "
+		       "Trying to continue but you better\nfix this issue or "
+		       "report it to linux-mips@linux-mips.org or your "
+		       "vendor.\n", name);
+#ifdef CONFIG_PCI_DOMAINS
+		panic("To avoid data corruption io_map_base MUST be set with "
+		      "multiple PCI domains.");
+#endif
+	}
+
+	return (void __iomem *) (ctrl->io_map_base + port);
+}
+
+/*
+ * Create a virtual mapping cookie for a PCI BAR (memory or IO)
+ */
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+	unsigned long start = pci_resource_start(dev, bar);
+	unsigned long len = pci_resource_len(dev, bar);
+	unsigned long flags = pci_resource_flags(dev, bar);
+
+	if (!len || !start)
+		return NULL;
+	if (maxlen && len > maxlen)
+		len = maxlen;
+	if (flags & IORESOURCE_IO)
+		return ioport_map_pci(dev, start, len);
+	if (flags & IORESOURCE_MEM) {
+		if (flags & IORESOURCE_CACHEABLE)
+			return ioremap(start, len);
+		return ioremap_nocache(start, len);
+	}
+	/* What? */
+	return NULL;
+}
+
+EXPORT_SYMBOL(pci_iomap);
+
+void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
+{
+	iounmap(addr);
+}
+
+EXPORT_SYMBOL(pci_iounmap);
diff --git a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c
index f4ac5bb..d51d5cb 100644
--- a/arch/mips/lib/iomap.c
+++ b/arch/mips/lib/iomap.c
@@ -1,78 +1,227 @@
 /*
- *  iomap.c, Memory Mapped I/O routines for MIPS architecture.
+ * Implement the default iomap interfaces
  *
- *  This code is based on lib/iomap.c, by Linus Torvalds.
- *
- *  Copyright (C) 2004-2005  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
- *
- *  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
+ * (C) Copyright 2004 Linus Torvalds
+ * (C) Copyright 2006 Ralf Baechle <ralf@linux-mips.org>
+ * (C) Copyright 2007 MIPS Technologies, Inc.
+ *     written by Ralf Baechle <ralf@linux-mips.org>
  */
-#include <linux/ioport.h>
-#include <linux/module.h>
 #include <linux/pci.h>
-
+#include <linux/module.h>
 #include <asm/io.h>
 
+/*
+ * Read/write from/to an (offsettable) iomem cookie. It might be a PIO
+ * access or a MMIO access, these functions don't care. The info is
+ * encoded in the hardware mapping set up by the mapping functions
+ * (or the cookie itself, depending on implementation and hw).
+ *
+ * The generic routines don't assume any hardware mappings, and just
+ * encode the PIO/MMIO as part of the cookie. They coldly assume that
+ * the MMIO IO mappings are not in the low address range.
+ *
+ * Architectures for which this is not true can't use this generic
+ * implementation and should do their own copy.
+ */
+
+#define PIO_MASK	0x0ffffUL
+
+unsigned int ioread8(void __iomem *addr)
+{
+	return readb(addr);
+}
+
+EXPORT_SYMBOL(ioread8);
+
+unsigned int ioread16(void __iomem *addr)
+{
+	return readw(addr);
+}
+
+EXPORT_SYMBOL(ioread16);
+
+unsigned int ioread16be(void __iomem *addr)
+{
+	return be16_to_cpu(__raw_readw(addr));
+}
+
+EXPORT_SYMBOL(ioread16be);
+
+unsigned int ioread32(void __iomem *addr)
+{
+	return readl(addr);
+}
+
+EXPORT_SYMBOL(ioread32);
+
+unsigned int ioread32be(void __iomem *addr)
+{
+	return be32_to_cpu(__raw_readl(addr));
+}
+
+EXPORT_SYMBOL(ioread32be);
+
+void iowrite8(u8 val, void __iomem *addr)
+{
+	writeb(val, addr);
+}
+
+EXPORT_SYMBOL(iowrite8);
+
+void iowrite16(u16 val, void __iomem *addr)
+{
+	writew(val, addr);
+}
+
+EXPORT_SYMBOL(iowrite16);
+
+void iowrite16be(u16 val, void __iomem *addr)
+{
+	__raw_writew(cpu_to_be16(val), addr);
+}
+
+EXPORT_SYMBOL(iowrite16be);
+
+void iowrite32(u32 val, void __iomem *addr)
+{
+	writel(val, addr);
+}
+
+EXPORT_SYMBOL(iowrite32);
+
+void iowrite32be(u32 val, void __iomem *addr)
+{
+	__raw_writel(cpu_to_be32(val), addr);
+}
+
+EXPORT_SYMBOL(iowrite32be);
+
+/*
+ * These are the "repeat MMIO read/write" functions.
+ * Note the "__raw" accesses, since we don't want to
+ * convert to CPU byte order. We write in "IO byte
+ * order" (we also don't have IO barriers).
+ */
+static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
+{
+	while (--count >= 0) {
+		u8 data = __raw_readb(addr);
+		*dst = data;
+		dst++;
+	}
+}
+
+static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
+{
+	while (--count >= 0) {
+		u16 data = __raw_readw(addr);
+		*dst = data;
+		dst++;
+	}
+}
+
+static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
+{
+	while (--count >= 0) {
+		u32 data = __raw_readl(addr);
+		*dst = data;
+		dst++;
+	}
+}
+
+static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
+{
+	while (--count >= 0) {
+		__raw_writeb(*src, addr);
+		src++;
+	}
+}
+
+static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
+{
+	while (--count >= 0) {
+		__raw_writew(*src, addr);
+		src++;
+	}
+}
+
+static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
+{
+	while (--count >= 0) {
+		__raw_writel(*src, addr);
+		src++;
+	}
+}
+
+void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	mmio_insb(addr, dst, count);
+}
+
+EXPORT_SYMBOL(ioread8_rep);
+
+void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	mmio_insw(addr, dst, count);
+}
+
+EXPORT_SYMBOL(ioread16_rep);
+
+void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	mmio_insl(addr, dst, count);
+}
+
+EXPORT_SYMBOL(ioread32_rep);
+
+void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	mmio_outsb(addr, src, count);
+}
+
+EXPORT_SYMBOL(iowrite8_rep);
+
+void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	mmio_outsw(addr, src, count);
+}
+
+EXPORT_SYMBOL(iowrite16_rep);
+
+void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	mmio_outsl(addr, src, count);
+}
+
+EXPORT_SYMBOL(iowrite32_rep);
+
+/*
+ * Create a virtual mapping cookie for an IO port range
+ *
+ * This uses the same mapping are as the in/out family which has to be setup
+ * by the platform initialization code.
+ *
+ * Just to make matters somewhat more interesting on MIPS systems with
+ * multiple host bridge each will have it's own ioport address space.
+ */
+static void __iomem *ioport_map_legacy(unsigned long port, unsigned int nr)
+{
+	return (void __iomem *) (mips_io_port_base + port);
+}
+
 void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
-	unsigned long end;
-
-	end = port + nr - 1UL;
-	if (ioport_resource.start > port ||
-	    ioport_resource.end < end || port > end)
+	if (port > PIO_MASK)
 		return NULL;
 
-	return (void __iomem *)(mips_io_port_base + port);
+	return ioport_map_legacy(port, nr);
 }
 
+EXPORT_SYMBOL(ioport_map);
+
 void ioport_unmap(void __iomem *addr)
 {
+	/* Nothing to do */
 }
-EXPORT_SYMBOL(ioport_map);
+
 EXPORT_SYMBOL(ioport_unmap);
-
-void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
-{
-	unsigned long start, len, flags;
-
-	if (dev == NULL)
-		return NULL;
-
-	start = pci_resource_start(dev, bar);
-	len = pci_resource_len(dev, bar);
-	if (!start || !len)
-		return NULL;
-
-	if (maxlen != 0 && len > maxlen)
-		len = maxlen;
-
-	flags = pci_resource_flags(dev, bar);
-	if (flags & IORESOURCE_IO)
-		return ioport_map(start, len);
-	if (flags & IORESOURCE_MEM) {
-		if (flags & IORESOURCE_CACHEABLE)
-			return ioremap_cachable(start, len);
-		return ioremap_nocache(start, len);
-	}
-
-	return NULL;
-}
-
-void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
-{
-	iounmap(addr);
-}
-EXPORT_SYMBOL(pci_iomap);
-EXPORT_SYMBOL(pci_iounmap);
diff --git a/arch/mips/lib/memcpy-inatomic.S b/arch/mips/lib/memcpy-inatomic.S
new file mode 100644
index 0000000..3a534b2
--- /dev/null
+++ b/arch/mips/lib/memcpy-inatomic.S
@@ -0,0 +1,436 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Unified implementation of memcpy, memmove and the __copy_user backend.
+ *
+ * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
+ * Copyright (C) 2002 Broadcom, Inc.
+ *   memcpy/copy_user author: Mark Vandevoorde
+ *
+ * Mnemonic names for arguments to memcpy/__copy_user
+ */
+
+/*
+ * Hack to resolve longstanding prefetch issue
+ *
+ * Prefetching may be fatal on some systems if we're prefetching beyond the
+ * end of memory on some systems.  It's also a seriously bad idea on non
+ * dma-coherent systems.
+ */
+#if !defined(CONFIG_DMA_COHERENT) || !defined(CONFIG_DMA_IP27)
+#undef CONFIG_CPU_HAS_PREFETCH
+#endif
+#ifdef CONFIG_MIPS_MALTA
+#undef CONFIG_CPU_HAS_PREFETCH
+#endif
+
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+#define dst a0
+#define src a1
+#define len a2
+
+/*
+ * Spec
+ *
+ * memcpy copies len bytes from src to dst and sets v0 to dst.
+ * It assumes that
+ *   - src and dst don't overlap
+ *   - src is readable
+ *   - dst is writable
+ * memcpy uses the standard calling convention
+ *
+ * __copy_user copies up to len bytes from src to dst and sets a2 (len) to
+ * the number of uncopied bytes due to an exception caused by a read or write.
+ * __copy_user assumes that src and dst don't overlap, and that the call is
+ * implementing one of the following:
+ *   copy_to_user
+ *     - src is readable  (no exceptions when reading src)
+ *   copy_from_user
+ *     - dst is writable  (no exceptions when writing dst)
+ * __copy_user uses a non-standard calling convention; see
+ * include/asm-mips/uaccess.h
+ *
+ * When an exception happens on a load, the handler must
+ # ensure that all of the destination buffer is overwritten to prevent
+ * leaking information to user mode programs.
+ */
+
+/*
+ * Implementation
+ */
+
+/*
+ * The exception handler for loads requires that:
+ *  1- AT contain the address of the byte just past the end of the source
+ *     of the copy,
+ *  2- src_entry <= src < AT, and
+ *  3- (dst - src) == (dst_entry - src_entry),
+ * The _entry suffix denotes values when __copy_user was called.
+ *
+ * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user
+ * (2) is met by incrementing src by the number of bytes copied
+ * (3) is met by not doing loads between a pair of increments of dst and src
+ *
+ * The exception handlers for stores adjust len (if necessary) and return.
+ * These handlers do not need to overwrite any data.
+ *
+ * For __rmemcpy and memmove an exception is always a kernel bug, therefore
+ * they're not protected.
+ */
+
+#define EXC(inst_reg,addr,handler)		\
+9:	inst_reg, addr;				\
+	.section __ex_table,"a";		\
+	PTR	9b, handler;			\
+	.previous
+
+/*
+ * Only on the 64-bit kernel we can made use of 64-bit registers.
+ */
+#ifdef CONFIG_64BIT
+#define USE_DOUBLE
+#endif
+
+#ifdef USE_DOUBLE
+
+#define LOAD   ld
+#define LOADL  ldl
+#define LOADR  ldr
+#define STOREL sdl
+#define STORER sdr
+#define STORE  sd
+#define ADD    daddu
+#define SUB    dsubu
+#define SRL    dsrl
+#define SRA    dsra
+#define SLL    dsll
+#define SLLV   dsllv
+#define SRLV   dsrlv
+#define NBYTES 8
+#define LOG_NBYTES 3
+
+/*
+ * As we are sharing code base with the mips32 tree (which use the o32 ABI
+ * register definitions). We need to redefine the register definitions from
+ * the n64 ABI register naming to the o32 ABI register naming.
+ */
+#undef t0
+#undef t1
+#undef t2
+#undef t3
+#define t0	$8
+#define t1	$9
+#define t2	$10
+#define t3	$11
+#define t4	$12
+#define t5	$13
+#define t6	$14
+#define t7	$15
+
+#else
+
+#define LOAD   lw
+#define LOADL  lwl
+#define LOADR  lwr
+#define STOREL swl
+#define STORER swr
+#define STORE  sw
+#define ADD    addu
+#define SUB    subu
+#define SRL    srl
+#define SLL    sll
+#define SRA    sra
+#define SLLV   sllv
+#define SRLV   srlv
+#define NBYTES 4
+#define LOG_NBYTES 2
+
+#endif /* USE_DOUBLE */
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define LDFIRST LOADR
+#define LDREST  LOADL
+#define STFIRST STORER
+#define STREST  STOREL
+#define SHIFT_DISCARD SLLV
+#else
+#define LDFIRST LOADL
+#define LDREST  LOADR
+#define STFIRST STOREL
+#define STREST  STORER
+#define SHIFT_DISCARD SRLV
+#endif
+
+#define FIRST(unit) ((unit)*NBYTES)
+#define REST(unit)  (FIRST(unit)+NBYTES-1)
+#define UNIT(unit)  FIRST(unit)
+
+#define ADDRMASK (NBYTES-1)
+
+	.text
+	.set	noreorder
+	.set	noat
+
+/*
+ * A combined memcpy/__copy_user
+ * __copy_user sets len to 0 for success; else to an upper bound of
+ * the number of uncopied bytes.
+ * memcpy sets v0 to dst.
+ */
+	.align	5
+LEAF(__copy_user_inatomic)
+	/*
+	 * Note: dst & src may be unaligned, len may be 0
+	 * Temps
+	 */
+#define rem t8
+
+	/*
+	 * The "issue break"s below are very approximate.
+	 * Issue delays for dcache fills will perturb the schedule, as will
+	 * load queue full replay traps, etc.
+	 *
+	 * If len < NBYTES use byte operations.
+	 */
+	PREF(	0, 0(src) )
+	PREF(	1, 0(dst) )
+	sltu	t2, len, NBYTES
+	and	t1, dst, ADDRMASK
+	PREF(	0, 1*32(src) )
+	PREF(	1, 1*32(dst) )
+	bnez	t2, copy_bytes_checklen
+	 and	t0, src, ADDRMASK
+	PREF(	0, 2*32(src) )
+	PREF(	1, 2*32(dst) )
+	bnez	t1, dst_unaligned
+	 nop
+	bnez	t0, src_unaligned_dst_aligned
+	/*
+	 * use delay slot for fall-through
+	 * src and dst are aligned; need to compute rem
+	 */
+both_aligned:
+	 SRL	t0, len, LOG_NBYTES+3    # +3 for 8 units/iter
+	beqz	t0, cleanup_both_aligned # len < 8*NBYTES
+	 and	rem, len, (8*NBYTES-1)	 # rem = len % (8*NBYTES)
+	PREF(	0, 3*32(src) )
+	PREF(	1, 3*32(dst) )
+	.align	4
+1:
+EXC(	LOAD	t0, UNIT(0)(src),	l_exc)
+EXC(	LOAD	t1, UNIT(1)(src),	l_exc_copy)
+EXC(	LOAD	t2, UNIT(2)(src),	l_exc_copy)
+EXC(	LOAD	t3, UNIT(3)(src),	l_exc_copy)
+	SUB	len, len, 8*NBYTES
+EXC(	LOAD	t4, UNIT(4)(src),	l_exc_copy)
+EXC(	LOAD	t7, UNIT(5)(src),	l_exc_copy)
+	STORE	t0, UNIT(0)(dst)
+	STORE	t1, UNIT(1)(dst)
+EXC(	LOAD	t0, UNIT(6)(src),	l_exc_copy)
+EXC(	LOAD	t1, UNIT(7)(src),	l_exc_copy)
+	ADD	src, src, 8*NBYTES
+	ADD	dst, dst, 8*NBYTES
+	STORE	t2, UNIT(-6)(dst)
+	STORE	t3, UNIT(-5)(dst)
+	STORE	t4, UNIT(-4)(dst)
+	STORE	t7, UNIT(-3)(dst)
+	STORE	t0, UNIT(-2)(dst)
+	STORE	t1, UNIT(-1)(dst)
+	PREF(	0, 8*32(src) )
+	PREF(	1, 8*32(dst) )
+	bne	len, rem, 1b
+	 nop
+
+	/*
+	 * len == rem == the number of bytes left to copy < 8*NBYTES
+	 */
+cleanup_both_aligned:
+	beqz	len, done
+	 sltu	t0, len, 4*NBYTES
+	bnez	t0, less_than_4units
+	 and	rem, len, (NBYTES-1)	# rem = len % NBYTES
+	/*
+	 * len >= 4*NBYTES
+	 */
+EXC(	LOAD	t0, UNIT(0)(src),	l_exc)
+EXC(	LOAD	t1, UNIT(1)(src),	l_exc_copy)
+EXC(	LOAD	t2, UNIT(2)(src),	l_exc_copy)
+EXC(	LOAD	t3, UNIT(3)(src),	l_exc_copy)
+	SUB	len, len, 4*NBYTES
+	ADD	src, src, 4*NBYTES
+	STORE	t0, UNIT(0)(dst)
+	STORE	t1, UNIT(1)(dst)
+	STORE	t2, UNIT(2)(dst)
+	STORE	t3, UNIT(3)(dst)
+	beqz	len, done
+	 ADD	dst, dst, 4*NBYTES
+less_than_4units:
+	/*
+	 * rem = len % NBYTES
+	 */
+	beq	rem, len, copy_bytes
+	 nop
+1:
+EXC(	LOAD	t0, 0(src),		l_exc)
+	ADD	src, src, NBYTES
+	SUB	len, len, NBYTES
+	STORE	t0, 0(dst)
+	bne	rem, len, 1b
+	 ADD	dst, dst, NBYTES
+
+	/*
+	 * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
+	 * A loop would do only a byte at a time with possible branch
+	 * mispredicts.  Can't do an explicit LOAD dst,mask,or,STORE
+	 * because can't assume read-access to dst.  Instead, use
+	 * STREST dst, which doesn't require read access to dst.
+	 *
+	 * This code should perform better than a simple loop on modern,
+	 * wide-issue mips processors because the code has fewer branches and
+	 * more instruction-level parallelism.
+	 */
+#define bits t2
+	beqz	len, done
+	 ADD	t1, dst, len	# t1 is just past last byte of dst
+	li	bits, 8*NBYTES
+	SLL	rem, len, 3	# rem = number of bits to keep
+EXC(	LOAD	t0, 0(src),		l_exc)
+	SUB	bits, bits, rem	# bits = number of bits to discard
+	SHIFT_DISCARD t0, t0, bits
+	STREST	t0, -1(t1)
+	jr	ra
+	 move	len, zero
+dst_unaligned:
+	/*
+	 * dst is unaligned
+	 * t0 = src & ADDRMASK
+	 * t1 = dst & ADDRMASK; T1 > 0
+	 * len >= NBYTES
+	 *
+	 * Copy enough bytes to align dst
+	 * Set match = (src and dst have same alignment)
+	 */
+#define match rem
+EXC(	LDFIRST	t3, FIRST(0)(src),	l_exc)
+	ADD	t2, zero, NBYTES
+EXC(	LDREST	t3, REST(0)(src),	l_exc_copy)
+	SUB	t2, t2, t1	# t2 = number of bytes copied
+	xor	match, t0, t1
+	STFIRST t3, FIRST(0)(dst)
+	beq	len, t2, done
+	 SUB	len, len, t2
+	ADD	dst, dst, t2
+	beqz	match, both_aligned
+	 ADD	src, src, t2
+
+src_unaligned_dst_aligned:
+	SRL	t0, len, LOG_NBYTES+2    # +2 for 4 units/iter
+	PREF(	0, 3*32(src) )
+	beqz	t0, cleanup_src_unaligned
+	 and	rem, len, (4*NBYTES-1)   # rem = len % 4*NBYTES
+	PREF(	1, 3*32(dst) )
+1:
+/*
+ * Avoid consecutive LD*'s to the same register since some mips
+ * implementations can't issue them in the same cycle.
+ * It's OK to load FIRST(N+1) before REST(N) because the two addresses
+ * are to the same unit (unless src is aligned, but it's not).
+ */
+EXC(	LDFIRST	t0, FIRST(0)(src),	l_exc)
+EXC(	LDFIRST	t1, FIRST(1)(src),	l_exc_copy)
+	SUB     len, len, 4*NBYTES
+EXC(	LDREST	t0, REST(0)(src),	l_exc_copy)
+EXC(	LDREST	t1, REST(1)(src),	l_exc_copy)
+EXC(	LDFIRST	t2, FIRST(2)(src),	l_exc_copy)
+EXC(	LDFIRST	t3, FIRST(3)(src),	l_exc_copy)
+EXC(	LDREST	t2, REST(2)(src),	l_exc_copy)
+EXC(	LDREST	t3, REST(3)(src),	l_exc_copy)
+	PREF(	0, 9*32(src) )		# 0 is PREF_LOAD  (not streamed)
+	ADD	src, src, 4*NBYTES
+#ifdef CONFIG_CPU_SB1
+	nop				# improves slotting
+#endif
+	STORE	t0, UNIT(0)(dst)
+	STORE	t1, UNIT(1)(dst)
+	STORE	t2, UNIT(2)(dst)
+	STORE	t3, UNIT(3)(dst)
+	PREF(	1, 9*32(dst) )     	# 1 is PREF_STORE (not streamed)
+	bne	len, rem, 1b
+	 ADD	dst, dst, 4*NBYTES
+
+cleanup_src_unaligned:
+	beqz	len, done
+	 and	rem, len, NBYTES-1  # rem = len % NBYTES
+	beq	rem, len, copy_bytes
+	 nop
+1:
+EXC(	LDFIRST t0, FIRST(0)(src),	l_exc)
+EXC(	LDREST	t0, REST(0)(src),	l_exc_copy)
+	ADD	src, src, NBYTES
+	SUB	len, len, NBYTES
+	STORE	t0, 0(dst)
+	bne	len, rem, 1b
+	 ADD	dst, dst, NBYTES
+
+copy_bytes_checklen:
+	beqz	len, done
+	 nop
+copy_bytes:
+	/* 0 < len < NBYTES  */
+#define COPY_BYTE(N)			\
+EXC(	lb	t0, N(src), l_exc);	\
+	SUB	len, len, 1;		\
+	beqz	len, done;		\
+	 sb	t0, N(dst)
+
+	COPY_BYTE(0)
+	COPY_BYTE(1)
+#ifdef USE_DOUBLE
+	COPY_BYTE(2)
+	COPY_BYTE(3)
+	COPY_BYTE(4)
+	COPY_BYTE(5)
+#endif
+EXC(	lb	t0, NBYTES-2(src), l_exc)
+	SUB	len, len, 1
+	jr	ra
+	 sb	t0, NBYTES-2(dst)
+done:
+	jr	ra
+	 nop
+	END(__copy_user_inatomic)
+
+l_exc_copy:
+	/*
+	 * Copy bytes from src until faulting load address (or until a
+	 * lb faults)
+	 *
+	 * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28)
+	 * may be more than a byte beyond the last address.
+	 * Hence, the lb below may get an exception.
+	 *
+	 * Assumes src < THREAD_BUADDR($28)
+	 */
+	LOAD	t0, TI_TASK($28)
+	 nop
+	LOAD	t0, THREAD_BUADDR(t0)
+1:
+EXC(	lb	t1, 0(src),	l_exc)
+	ADD	src, src, 1
+	sb	t1, 0(dst)	# can't fault -- we're copy_from_user
+	bne	src, t0, 1b
+	 ADD	dst, dst, 1
+l_exc:
+	LOAD	t0, TI_TASK($28)
+	 nop
+	LOAD	t0, THREAD_BUADDR(t0)	# t0 is just past last good address
+	 nop
+	SUB	len, AT, t0		# len number of uncopied bytes
+	jr	ra
+	 nop
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 125a4a8..f08ae71c 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -61,8 +61,6 @@
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
-unsigned long highstart_pfn, highend_pfn;
-
 /*
  * We have up to 8 empty zeroed pages so we can map one of the right colour
  * when needed.  This is necessary only on R4000 / R4400 SC and MC versions
@@ -261,6 +259,8 @@
 
 
 #ifdef CONFIG_HIGHMEM
+unsigned long highstart_pfn, highend_pfn;
+
 pte_t *kmap_pte;
 pgprot_t kmap_prot;
 
@@ -314,8 +314,6 @@
 }
 
 #ifndef CONFIG_NEED_MULTIPLE_NODES
-extern void pagetable_init(void);
-
 static int __init page_is_ram(unsigned long pagenr)
 {
 	int i;
diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c
index 4a61e62..575e401 100644
--- a/arch/mips/mm/pgtable-32.c
+++ b/arch/mips/mm/pgtable-32.c
@@ -11,6 +11,7 @@
 #include <linux/highmem.h>
 #include <asm/fixmap.h>
 #include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 
 void pgd_init(unsigned long page)
 {
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c
index c46eb65..e4b565a 100644
--- a/arch/mips/mm/pgtable-64.c
+++ b/arch/mips/mm/pgtable-64.c
@@ -10,6 +10,7 @@
 #include <linux/mm.h>
 #include <asm/fixmap.h>
 #include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 
 void pgd_init(unsigned long page)
 {
diff --git a/arch/mips/pci/fixup-sni.c b/arch/mips/pci/fixup-sni.c
index a176f2c..0c9a473 100644
--- a/arch/mips/pci/fixup-sni.c
+++ b/arch/mips/pci/fixup-sni.c
@@ -15,7 +15,7 @@
 #include <asm/sni.h>
 
 /*
- * Shortcuts ...
+ * PCIMT Shortcuts ...
  */
 #define SCSI	PCIMT_IRQ_SCSI
 #define ETH	PCIMT_IRQ_ETHERNET
@@ -67,6 +67,50 @@
 	{     0, INTD, INTA, INTB, INTC },	/* Slot 4 */
 };
 
+static char irq_tab_rm300e[5][5] __initdata = {
+	/*       INTA  INTB  INTC  INTD */
+	{     0,    0,    0,    0,    0 },	/* HOST bridge */
+	{  SCSI, SCSI, SCSI, SCSI, SCSI },	/* SCSI */
+	{     0, INTC, INTD, INTA, INTB },	/* Bridge/i960 */
+	{     0, INTD, INTA, INTB, INTC },	/* Slot 1 */
+	{     0, INTA, INTB, INTC, INTD },	/* Slot 2 */
+};
+#undef SCSI
+#undef ETH
+#undef INTA
+#undef INTB
+#undef INTC
+#undef INTD
+
+
+/*
+ * PCIT Shortcuts ...
+ */
+#define SCSI0	PCIT_IRQ_SCSI0
+#define SCSI1	PCIT_IRQ_SCSI1
+#define ETH	PCIT_IRQ_ETHERNET
+#define INTA	PCIT_IRQ_INTA
+#define INTB	PCIT_IRQ_INTB
+#define INTC	PCIT_IRQ_INTC
+#define INTD	PCIT_IRQ_INTD
+
+static char irq_tab_pcit[13][5] __initdata = {
+	/*       INTA  INTB  INTC  INTD */
+	{     0,     0,     0,     0,     0 },	/* HOST bridge */
+	{ SCSI0, SCSI0, SCSI0, SCSI0, SCSI0 },	/* SCSI */
+	{ SCSI1, SCSI1, SCSI1, SCSI1, SCSI1 },	/* SCSI */
+	{   ETH,   ETH,   ETH,   ETH,   ETH },	/* Ethernet */
+	{     0,  INTA,  INTB,  INTC,  INTD },	/* PCI-PCI bridge */
+	{     0,     0,     0,     0,     0 },	/* Unused */
+	{     0,     0,     0,     0,     0 },	/* Unused */
+	{     0,     0,     0,     0,     0 },	/* Unused */
+	{     0,  INTA,  INTB,  INTC,  INTD },	/* Slot 1 */
+	{     0,  INTB,  INTC,  INTD,  INTA },	/* Slot 2 */
+	{     0,  INTC,  INTD,  INTA,  INTB },	/* Slot 3 */
+	{     0,  INTD,  INTA,  INTB,  INTC },	/* Slot 4 */
+	{     0,  INTA,  INTB,  INTC,  INTD },	/* Slot 5 */
+};
+
 static inline int is_rm300_revd(void)
 {
 	unsigned char csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
@@ -76,10 +120,24 @@
 
 int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-	if (is_rm300_revd())
-		return irq_tab_rm300d[slot][pin];
+	switch (sni_brd_type) {
+	case SNI_BRD_PCI_TOWER:
+	case SNI_BRD_PCI_TOWER_CPLUS:
+	        return irq_tab_pcit[slot][pin];
 
-	return irq_tab_rm200[slot][pin];
+	case SNI_BRD_PCI_MTOWER:
+	        if (is_rm300_revd())
+		        return irq_tab_rm300d[slot][pin];
+	        /* fall through */
+
+	case SNI_BRD_PCI_DESKTOP:
+	        return irq_tab_rm200[slot][pin];
+
+	case SNI_BRD_PCI_MTOWER_CPLUS:
+	        return irq_tab_rm300e[slot][pin];
+	}
+
+	return 0;
 }
 
 /* Do platform specific device initialization at pci_enable_device() time */
diff --git a/arch/mips/pci/ops-sni.c b/arch/mips/pci/ops-sni.c
index 2b0ccd6..fa2d2c6 100644
--- a/arch/mips/pci/ops-sni.c
+++ b/arch/mips/pci/ops-sni.c
@@ -83,7 +83,82 @@
 	return 0;
 }
 
-struct pci_ops sni_pci_ops = {
+struct pci_ops sni_pcimt_ops = {
 	.read = pcimt_read,
 	.write = pcimt_write,
 };
+
+static int pcit_set_config_address(unsigned int busno, unsigned int devfn, int reg)
+{
+	if ((devfn > 255) || (reg > 255) || (busno > 255))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	outl ((1 << 31) | ((busno & 0xff) << 16) | ((devfn & 0xff) << 8) | (reg & 0xfc), 0xcf8);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pcit_read(struct pci_bus *bus, unsigned int devfn, int reg,
+		      int size, u32 * val)
+{
+	int res;
+
+	/*
+	 * on bus 0 we need to check, whether there is a device answering
+	 * for the devfn by doing a config write and checking the result. If
+	 * we don't do it, we will get a data bus error
+	 */
+	if (bus->number == 0) {
+		pcit_set_config_address (0, 0, 0x68);
+		outl (inl (0xcfc) | 0xc0000000, 0xcfc);
+		if ((res = pcit_set_config_address(0, devfn, 0)))
+			return res;
+		outl (0xffffffff, 0xcfc);
+		pcit_set_config_address (0, 0, 0x68);
+		if (inl(0xcfc) & 0x100000)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	if ((res = pcit_set_config_address(bus->number, devfn, reg)))
+		return res;
+
+	switch (size) {
+	case 1:
+		*val = inb(PCIMT_CONFIG_DATA + (reg & 3));
+		break;
+	case 2:
+		*val = inw(PCIMT_CONFIG_DATA + (reg & 2));
+		break;
+	case 4:
+		*val = inl(PCIMT_CONFIG_DATA);
+		break;
+	}
+	return 0;
+}
+
+static int pcit_write(struct pci_bus *bus, unsigned int devfn, int reg,
+		       int size, u32 val)
+{
+	int res;
+
+	if ((res = pcit_set_config_address(bus->number, devfn, reg)))
+		return res;
+
+	switch (size) {
+	case 1:
+		outb (val, PCIMT_CONFIG_DATA + (reg & 3));
+		break;
+	case 2:
+		outw (val, PCIMT_CONFIG_DATA + (reg & 2));
+		break;
+	case 4:
+		outl (val, PCIMT_CONFIG_DATA);
+		break;
+	}
+
+	return 0;
+}
+
+
+struct pci_ops sni_pcit_ops = {
+	.read = pcit_read,
+	.write = pcit_write,
+};
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 5ace3686..697a7e4 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -79,6 +79,14 @@
 {
 	*hose_tail = hose;
 	hose_tail = &hose->next;
+
+	/*
+	 * Do not panic here but later - this might hapen before console init.
+	 */
+	if (!hose->io_map_base) {
+		printk(KERN_WARNING
+		       "registering PCI controller with io_map_base unset\n");
+	}
 }
 
 /* Most MIPS systems have straight-forward swizzling needs.  */
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
index 0e3d535..fe8a106 100644
--- a/arch/mips/sgi-ip27/ip27-memory.c
+++ b/arch/mips/sgi-ip27/ip27-memory.c
@@ -21,6 +21,7 @@
 #include <linux/pfn.h>
 #include <linux/highmem.h>
 #include <asm/page.h>
+#include <asm/pgalloc.h>
 #include <asm/sections.h>
 
 #include <asm/sn/arch.h>
@@ -503,7 +504,6 @@
 	/* We got nothing to free here ...  */
 }
 
-extern void pagetable_init(void);
 extern unsigned long setup_zero_pages(void);
 
 void __init paging_init(void)
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index 9ce5136..8c3c78c 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -190,7 +190,7 @@
 };
 
 static struct irqaction rt_irqaction = {
-	.handler	= ip27_rt_timer_interrupt,
+	.handler	= (irq_handler_t) ip27_rt_timer_interrupt,
 	.flags		= IRQF_DISABLED,
 	.mask		= CPU_MASK_NONE,
 	.name		= "timer"
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile
index a5eb0ad..e30809a 100644
--- a/arch/mips/sni/Makefile
+++ b/arch/mips/sni/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the SNI specific part of the kernel
 #
 
-obj-y	 	+= irq.o pcimt_scache.o reset.o setup.o
+obj-y += irq.o reset.o setup.o ds1216.o a20r.o rm200.o pcimt.o pcit.o time.o
 obj-$(CONFIG_CPU_BIG_ENDIAN) += sniprom.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
new file mode 100644
index 0000000..31ab80f
--- /dev/null
+++ b/arch/mips/sni/a20r.c
@@ -0,0 +1,227 @@
+/*
+ * A20R specific code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <asm/sni.h>
+#include <asm/time.h>
+#include <asm/ds1216.h>
+
+#define PORT(_base,_irq)				\
+	{						\
+		.iobase		= _base,		\
+		.irq		= _irq,			\
+		.uartclk	= 1843200,		\
+		.iotype		= UPIO_PORT,		\
+		.flags		= UPF_BOOT_AUTOCONF,	\
+	}
+
+static struct plat_serial8250_port a20r_data[] = {
+	PORT(0x3f8, 4),
+	PORT(0x2f8, 3),
+	{ },
+};
+
+static struct platform_device a20r_serial8250_device = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= a20r_data,
+	},
+};
+
+static struct resource snirm_82596_rsrc[] = {
+	{
+		.start = 0xb8000000,
+		.end   = 0xb8000004,
+		.flags = IORESOURCE_MEM
+	},
+	{
+		.start = 0xb8010000,
+		.end   = 0xb8010004,
+		.flags = IORESOURCE_MEM
+	},
+	{
+		.start = 0xbff00000,
+		.end   = 0xbff00020,
+		.flags = IORESOURCE_MEM
+	},
+	{
+		.start = 22,
+		.end   = 22,
+		.flags = IORESOURCE_IRQ
+	},
+	{
+		.flags = 0x01                /* 16bit mpu port access */
+	}
+};
+
+static struct platform_device snirm_82596_pdev = {
+	.name           = "snirm_82596",
+	.num_resources  = ARRAY_SIZE(snirm_82596_rsrc),
+	.resource       = snirm_82596_rsrc
+};
+
+static struct resource snirm_53c710_rsrc[] = {
+	{
+		.start = 0xb9000000,
+		.end   = 0xb90fffff,
+		.flags = IORESOURCE_MEM
+	},
+	{
+		.start = 19,
+		.end   = 19,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct platform_device snirm_53c710_pdev = {
+	.name           = "snirm_53c710",
+	.num_resources  = ARRAY_SIZE(snirm_53c710_rsrc),
+	.resource       = snirm_53c710_rsrc
+};
+
+static struct resource sc26xx_rsrc[] = {
+	{
+		.start = 0xbc070000,
+		.end   = 0xbc0700ff,
+		.flags = IORESOURCE_MEM
+	},
+	{
+		.start = 20,
+		.end   = 20,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct platform_device sc26xx_pdev = {
+	.name           = "SC26xx",
+	.num_resources  = ARRAY_SIZE(sc26xx_rsrc),
+	.resource       = sc26xx_rsrc
+};
+
+static u32 a20r_ack_hwint(void)
+{
+	u32 status = read_c0_status();
+
+	write_c0_status (status | 0x00010000);
+	asm volatile(
+	"	.set	push			\n"
+	"	.set	noat			\n"
+	"	.set	noreorder		\n"
+	"	lw	$1, 0(%0)		\n"
+	"	sb	$0, 0(%1)		\n"
+	"	sync				\n"
+	"	lb	%1, 0(%1)		\n"
+	"	b	1f			\n"
+	"	ori	%1, $1, 2		\n"
+	"	.align	8			\n"
+	"1:					\n"
+	"	nop				\n"
+	"	sw	%1, 0(%0)		\n"
+	"	sync				\n"
+	"	li	%1, 0x20		\n"
+	"2:					\n"
+	"	nop				\n"
+	"	bnez	%1,2b			\n"
+	"	addiu	%1, -1			\n"
+	"	sw	$1, 0(%0)		\n"
+	"	sync				\n"
+		".set   pop			\n"
+	:
+	: "Jr" (PCIMT_UCONF), "Jr" (0xbc000000));
+	write_c0_status(status);
+
+	return status;
+}
+
+static inline void unmask_a20r_irq(unsigned int irq)
+{
+	set_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE));
+	irq_enable_hazard();
+}
+
+static inline void mask_a20r_irq(unsigned int irq)
+{
+	clear_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE));
+	irq_disable_hazard();
+}
+
+static void end_a20r_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		a20r_ack_hwint();
+		unmask_a20r_irq(irq);
+	}
+}
+
+static struct irq_chip a20r_irq_type = {
+	.typename	= "A20R",
+	.ack		= mask_a20r_irq,
+	.mask		= mask_a20r_irq,
+	.mask_ack	= mask_a20r_irq,
+	.unmask		= unmask_a20r_irq,
+	.end		= end_a20r_irq,
+};
+
+/*
+ * hwint 0 receive all interrupts
+ */
+static void a20r_hwint(void)
+{
+	u32 cause, status;
+	int irq;
+
+	clear_c0_status (IE_IRQ0);
+	status = a20r_ack_hwint();
+	cause = read_c0_cause();
+
+	irq = ffs(((cause & status) >> 8) & 0xf8);
+	if (likely(irq > 0))
+		do_IRQ(SNI_A20R_IRQ_BASE + irq - 1);
+	set_c0_status(IE_IRQ0);
+}
+
+void __init sni_a20r_irq_init(void)
+{
+	int i;
+
+	for (i = SNI_A20R_IRQ_BASE + 2 ; i < SNI_A20R_IRQ_BASE + 8; i++)
+		set_irq_chip(i, &a20r_irq_type);
+	sni_hwint = a20r_hwint;
+	change_c0_status(ST0_IM, IE_IRQ0);
+	setup_irq (SNI_A20R_IRQ_BASE + 3, &sni_isa_irq);
+}
+
+void sni_a20r_init(void)
+{
+	ds1216_base = (volatile unsigned char *) SNI_DS1216_A20R_BASE;
+	rtc_mips_get_time = ds1216_get_cmos_time;
+}
+
+static int __init snirm_a20r_setup_devinit(void)
+{
+	switch (sni_brd_type) {
+	case SNI_BRD_TOWER_OASIC:
+	case SNI_BRD_MINITOWER:
+	        platform_device_register(&snirm_82596_pdev);
+	        platform_device_register(&snirm_53c710_pdev);
+	        platform_device_register(&sc26xx_pdev);
+	        platform_device_register(&a20r_serial8250_device);
+	        break;
+	}
+
+	return 0;
+}
+
+device_initcall(snirm_a20r_setup_devinit);
diff --git a/arch/mips/sni/ds1216.c b/arch/mips/sni/ds1216.c
new file mode 100644
index 0000000..1d92732
--- /dev/null
+++ b/arch/mips/sni/ds1216.c
@@ -0,0 +1,81 @@
+
+#include <linux/bcd.h>
+#include <linux/time.h>
+
+#include <asm/ds1216.h>
+
+volatile unsigned char *ds1216_base;
+
+/*
+ * Read the 64 bit we'd like to have - It a series
+ * of 64 bits showing up in the LSB of the base register.
+ *
+ */
+static unsigned char *ds1216_read(void)
+{
+	static unsigned char	rdbuf[8];
+	unsigned char		c;
+	int			i, j;
+
+	for (i = 0; i < 8; i++) {
+		c = 0x0;
+		for (j = 0; j < 8; j++) {
+			c |= (*ds1216_base & 0x1) << j;
+		}
+		rdbuf[i] = c;
+	}
+
+	return rdbuf;
+}
+
+static void ds1216_switch_ds_to_clock(void)
+{
+	unsigned char magic[] = {
+		0xc5, 0x3a, 0xa3, 0x5c, 0xc5, 0x3a, 0xa3, 0x5c
+	};
+	int i,j,c;
+
+	/* Reset magic pointer */
+	c = *ds1216_base;
+
+	/* Write 64 bit magic to DS1216 */
+	for (i = 0; i < 8; i++) {
+		c = magic[i];
+		for (j = 0; j < 8; j++) {
+			*ds1216_base = c;
+			c = c >> 1;
+		}
+	}
+}
+
+unsigned long ds1216_get_cmos_time(void)
+{
+	unsigned char	*rdbuf;
+	unsigned int	year, month, date, hour, min, sec;
+
+	ds1216_switch_ds_to_clock();
+	rdbuf = ds1216_read();
+
+	sec = BCD2BIN(DS1216_SEC(rdbuf));
+	min = BCD2BIN(DS1216_MIN(rdbuf));
+	hour = BCD2BIN(DS1216_HOUR(rdbuf));
+	date = BCD2BIN(DS1216_DATE(rdbuf));
+	month = BCD2BIN(DS1216_MONTH(rdbuf));
+	year = BCD2BIN(DS1216_YEAR(rdbuf));
+
+	if (DS1216_1224(rdbuf) && DS1216_AMPM(rdbuf))
+		hour+=12;
+
+	if (year < 70)
+		year += 2000;
+	else
+		year += 1900;
+
+	return mktime(year, month, date, hour, min, sec);
+}
+
+int ds1216_set_rtc_mmss(unsigned long nowtime)
+{
+	printk("ds1216_set_rtc_mmss called but not implemented\n");
+	return -1;
+}
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c
index 039e8e5..ad5fc47 100644
--- a/arch/mips/sni/irq.c
+++ b/arch/mips/sni/irq.c
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 1992 Linus Torvalds
  * Copyright (C) 1994 - 2000 Ralf Baechle
+ * Copyright (C) 2006 Thomas Bogendoerfer
  */
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -15,153 +16,35 @@
 #include <asm/i8259.h>
 #include <asm/io.h>
 #include <asm/sni.h>
+#include <asm/irq.h>
+#include <asm/irq_cpu.h>
 
-static void enable_pciasic_irq(unsigned int irq)
-{
-	unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2);
-
-	*(volatile u8 *) PCIMT_IRQSEL |= mask;
-}
-
-void disable_pciasic_irq(unsigned int irq)
-{
-	unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2));
-
-	*(volatile u8 *) PCIMT_IRQSEL &= mask;
-}
-
-static void end_pciasic_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_pciasic_irq(irq);
-}
-
-static struct irq_chip pciasic_irq_type = {
-	.name = "ASIC-PCI",
-	.ack = disable_pciasic_irq,
-	.mask = disable_pciasic_irq,
-	.mask_ack = disable_pciasic_irq,
-	.unmask = enable_pciasic_irq,
-	.end = end_pciasic_irq,
-};
-
-/*
- * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
- * button interrupts.  Later ...
- */
-static void pciasic_hwint0(void)
-{
-	panic("Received int0 but no handler yet ...");
-}
-
-/* This interrupt was used for the com1 console on the first prototypes.  */
-static void pciasic_hwint2(void)
-{
-	/* I think this shouldn't happen on production machines.  */
-	panic("hwint2 and no handler yet");
-}
-
-/* hwint5 is the r4k count / compare interrupt  */
-static void pciasic_hwint5(void)
-{
-	panic("hwint5 and no handler yet");
-}
-
-static unsigned int ls1bit8(unsigned int x)
-{
-	int b = 7, s;
-
-	s = 4; if ((x & 0x0f) == 0) s = 0; b -= s; x <<= s;
-	s = 2; if ((x & 0x30) == 0) s = 0; b -= s; x <<= s;
-	s = 1; if ((x & 0x40) == 0) s = 0; b -= s;
-
-	return b;
-}
-
-/*
- * hwint 1 deals with EISA and SCSI interrupts,
- *
- * The EISA_INT bit in CSITPEND is high active, all others are low active.
- */
-static void pciasic_hwint1(void)
-{
-	u8 pend = *(volatile char *)PCIMT_CSITPEND;
-	unsigned long flags;
-
-	if (pend & IT_EISA) {
-		int irq;
-		/*
-		 * Note: ASIC PCI's builtin interrupt achknowledge feature is
-		 * broken.  Using it may result in loss of some or all i8259
-		 * interupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
-		 */
-		irq = i8259_irq();
-		if (unlikely(irq < 0))
-			return;
-
-		do_IRQ(irq);
-	}
-
-	if (!(pend & IT_SCSI)) {
-		flags = read_c0_status();
-		clear_c0_status(ST0_IM);
-		do_IRQ(PCIMT_IRQ_SCSI);
-		write_c0_status(flags);
-	}
-}
-
-/*
- * hwint 3 should deal with the PCI A - D interrupts,
- */
-static void pciasic_hwint3(void)
-{
-	u8 pend = *(volatile char *)PCIMT_CSITPEND;
-	int irq;
-
-	pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
-	clear_c0_status(IE_IRQ3);
-	irq = PCIMT_IRQ_INT2 + ls1bit8(pend);
-	do_IRQ(irq);
-	set_c0_status(IE_IRQ3);
-}
-
-/*
- * hwint 4 is used for only the onboard PCnet 32.
- */
-static void pciasic_hwint4(void)
-{
-	clear_c0_status(IE_IRQ4);
-	do_IRQ(PCIMT_IRQ_ETHERNET);
-	set_c0_status(IE_IRQ4);
-}
+void (*sni_hwint)(void);
 
 asmlinkage void plat_irq_dispatch(void)
 {
-	unsigned int pending = read_c0_status() & read_c0_cause();
-	static unsigned char led_cache;
-
-	*(volatile unsigned char *) PCIMT_CSLED = ++led_cache;
-
-	if (pending & 0x0800)
-		pciasic_hwint1();
-	else if (pending & 0x4000)
-		pciasic_hwint4();
-	else if (pending & 0x2000)
-		pciasic_hwint3();
-	else if (pending & 0x1000)
-		pciasic_hwint2();
-	else if (pending & 0x8000)
-		pciasic_hwint5();
-	else if (pending & 0x0400)
-		pciasic_hwint0();
+	sni_hwint();
 }
 
-void __init init_pciasic(void)
+/* ISA irq handler */
+static irqreturn_t sni_isa_irq_handler(int dummy, void *p)
 {
-	* (volatile u8 *) PCIMT_IRQSEL =
-		IT_EISA | IT_INTA | IT_INTB | IT_INTC | IT_INTD;
+	int irq;
+
+	irq = i8259_irq();
+	if (unlikely(irq < 0))
+		return IRQ_NONE;
+
+	do_IRQ(irq);
+	return IRQ_HANDLED;
 }
 
+struct irqaction sni_isa_irq = {
+	.handler = sni_isa_irq_handler,
+	.name = "ISA",
+	.flags = SA_SHIRQ
+};
+
 /*
  * On systems with i8259-style interrupt controllers we assume for
  * driver compatibility reasons interrupts 0 - 15 to be the i8295
@@ -169,14 +52,31 @@
  */
 void __init arch_init_irq(void)
 {
-	int i;
-
 	init_i8259_irqs();			/* Integrated i8259  */
-	init_pciasic();
+	switch (sni_brd_type) {
+	case SNI_BRD_10:
+	case SNI_BRD_10NEW:
+	case SNI_BRD_TOWER_OASIC:
+	case SNI_BRD_MINITOWER:
+	        sni_a20r_irq_init();
+	        break;
 
-	/* Actually we've got more interrupts to handle ...  */
-	for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_ETHERNET; i++)
-		set_irq_chip(i, &pciasic_irq_type);
+	case SNI_BRD_PCI_TOWER:
+	        sni_pcit_irq_init();
+	        break;
 
-	change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ2|IE_IRQ3|IE_IRQ4);
+	case SNI_BRD_PCI_TOWER_CPLUS:
+	        sni_pcit_cplus_irq_init();
+	        break;
+
+	case SNI_BRD_RM200:
+	        sni_rm200_irq_init();
+	        break;
+
+	case SNI_BRD_PCI_MTOWER:
+	case SNI_BRD_PCI_DESKTOP:
+	case SNI_BRD_PCI_MTOWER_CPLUS:
+	        sni_pcimt_irq_init();
+	        break;
+	}
 }
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c
new file mode 100644
index 0000000..6c0dad7
--- /dev/null
+++ b/arch/mips/sni/pcimt.c
@@ -0,0 +1,390 @@
+/*
+ * PCIMT specific code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/serial_8250.h>
+
+#include <asm/mc146818-time.h>
+#include <asm/sni.h>
+#include <asm/time.h>
+#include <asm/i8259.h>
+#include <asm/irq_cpu.h>
+
+#define cacheconf (*(volatile unsigned int *)PCIMT_CACHECONF)
+#define invspace (*(volatile unsigned int *)PCIMT_INVSPACE)
+
+static void __init sni_pcimt_sc_init(void)
+{
+	unsigned int scsiz, sc_size;
+
+	scsiz = cacheconf & 7;
+	if (scsiz == 0) {
+		printk("Second level cache is deactived.\n");
+		return;
+	}
+	if (scsiz >= 6) {
+		printk("Invalid second level cache size configured, "
+		       "deactivating second level cache.\n");
+		cacheconf = 0;
+		return;
+	}
+
+	sc_size = 128 << scsiz;
+	printk("%dkb second level cache detected, deactivating.\n", sc_size);
+	cacheconf = 0;
+}
+
+
+/*
+ * A bit more gossip about the iron we're running on ...
+ */
+static inline void sni_pcimt_detect(void)
+{
+	char boardtype[80];
+	unsigned char csmsr;
+	char *p = boardtype;
+	unsigned int asic;
+
+	csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
+
+	p += sprintf(p, "%s PCI", (csmsr & 0x80) ? "RM200" : "RM300");
+	if ((csmsr & 0x80) == 0)
+		p += sprintf(p, ", board revision %s",
+		             (csmsr & 0x20) ? "D" : "C");
+	asic = csmsr & 0x80;
+	asic = (csmsr & 0x08) ? asic : !asic;
+	p += sprintf(p, ", ASIC PCI Rev %s", asic ? "1.0" : "1.1");
+	printk("%s.\n", boardtype);
+}
+
+#define PORT(_base,_irq)				\
+	{						\
+		.iobase		= _base,		\
+		.irq		= _irq,			\
+		.uartclk	= 1843200,		\
+		.iotype		= UPIO_PORT,		\
+		.flags		= UPF_BOOT_AUTOCONF,	\
+	}
+
+static struct plat_serial8250_port pcimt_data[] = {
+	PORT(0x3f8, 4),
+	PORT(0x2f8, 3),
+	{ },
+};
+
+static struct platform_device pcimt_serial8250_device = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= pcimt_data,
+	},
+};
+
+static struct resource sni_io_resource = {
+	.start	= 0x00001000UL,
+	.end	= 0x03bfffffUL,
+	.name	= "PCIMT IO MEM",
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource pcimt_io_resources[] = {
+	{
+		.start	= 0x00,
+		.end	= 0x1f,
+		.name	= "dma1",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	=  0x40,
+		.end	= 0x5f,
+		.name	= "timer",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	=  0x60,
+		.end	= 0x6f,
+		.name	= "keyboard",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	=  0x80,
+		.end	= 0x8f,
+		.name	= "dma page reg",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	=  0xc0,
+		.end	= 0xdf,
+		.name	= "dma2",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	=  0xcfc,
+		.end	= 0xcff,
+		.name	= "PCI config data",
+		.flags	= IORESOURCE_BUSY
+	}
+};
+
+static struct resource sni_mem_resource = {
+	.start	= 0x10000000UL,
+	.end	= 0xffffffffUL,
+	.name	= "PCIMT PCI MEM",
+	.flags	= IORESOURCE_MEM
+};
+
+/*
+ * The RM200/RM300 has a few holes in it's PCI/EISA memory address space used
+ * for other purposes.  Be paranoid and allocate all of the before the PCI
+ * code gets a chance to to map anything else there ...
+ *
+ * This leaves the following areas available:
+ *
+ * 0x10000000 - 0x1009ffff (640kB) PCI/EISA/ISA Bus Memory
+ * 0x10100000 - 0x13ffffff ( 15MB) PCI/EISA/ISA Bus Memory
+ * 0x18000000 - 0x1fbfffff (124MB) PCI/EISA Bus Memory
+ * 0x1ff08000 - 0x1ffeffff (816kB) PCI/EISA Bus Memory
+ * 0xa0000000 - 0xffffffff (1.5GB) PCI/EISA Bus Memory
+ */
+static struct resource pcimt_mem_resources[] = {
+	{
+		.start	= 0x100a0000,
+		.end	= 0x100bffff,
+		.name	= "Video RAM area",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x100c0000,
+		.end	= 0x100fffff,
+		.name	= "ISA Reserved",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x14000000,
+		.end	= 0x17bfffff,
+		.name	= "PCI IO",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x17c00000,
+		.end	= 0x17ffffff,
+		.name	= "Cache Replacement Area",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1a000000,
+		.end	= 0x1a000003,
+		.name	= "PCI INT Acknowledge",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1fc00000,
+		.end	= 0x1fc7ffff,
+		.name	= "Boot PROM",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1fc80000,
+		.end	= 0x1fcfffff,
+		.name	= "Diag PROM",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1fd00000,
+		.end	= 0x1fdfffff,
+		.name	= "X-Bus",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1fe00000,
+		.end	= 0x1fefffff,
+		.name	= "BIOS map",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1ff00000,
+		.end	= 0x1ff7ffff,
+		.name	= "NVRAM / EEPROM",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1fff0000,
+		.end	= 0x1fffefff,
+		.name	= "ASIC PCI",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1ffff000,
+		.end	= 0x1fffffff,
+		.name	= "MP Agent",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x20000000,
+		.end	= 0x9fffffff,
+		.name	= "Main Memory",
+		.flags	= IORESOURCE_BUSY
+	}
+};
+
+static void __init sni_pcimt_resource_init(void)
+{
+	int i;
+
+	/* request I/O space for devices used on all i[345]86 PCs */
+	for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++)
+		request_resource(&ioport_resource, pcimt_io_resources + i);
+
+	/* request mem space for pcimt-specific devices */
+	for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++)
+		request_resource(&sni_mem_resource, pcimt_mem_resources + i);
+
+	ioport_resource.end = sni_io_resource.end;
+}
+
+extern struct pci_ops sni_pcimt_ops;
+
+static struct pci_controller sni_controller = {
+	.pci_ops	= &sni_pcimt_ops,
+	.mem_resource	= &sni_mem_resource,
+	.mem_offset	= 0x10000000UL,
+	.io_resource	= &sni_io_resource,
+	.io_offset	= 0x00000000UL
+};
+
+static void enable_pcimt_irq(unsigned int irq)
+{
+	unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2);
+
+	*(volatile u8 *) PCIMT_IRQSEL |= mask;
+}
+
+void disable_pcimt_irq(unsigned int irq)
+{
+	unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2));
+
+	*(volatile u8 *) PCIMT_IRQSEL &= mask;
+}
+
+static void end_pcimt_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_pcimt_irq(irq);
+}
+
+static struct irq_chip pcimt_irq_type = {
+	.typename = "PCIMT",
+	.ack = disable_pcimt_irq,
+	.mask = disable_pcimt_irq,
+	.mask_ack = disable_pcimt_irq,
+	.unmask = enable_pcimt_irq,
+	.end = end_pcimt_irq,
+};
+
+/*
+ * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
+ * button interrupts.  Later ...
+ */
+static void pcimt_hwint0(void)
+{
+	panic("Received int0 but no handler yet ...");
+}
+
+/*
+ * hwint 1 deals with EISA and SCSI interrupts,
+ *
+ * The EISA_INT bit in CSITPEND is high active, all others are low active.
+ */
+static void pcimt_hwint1(void)
+{
+	u8 pend = *(volatile char *)PCIMT_CSITPEND;
+	unsigned long flags;
+
+	if (pend & IT_EISA) {
+		int irq;
+		/*
+		 * Note: ASIC PCI's builtin interrupt achknowledge feature is
+		 * broken.  Using it may result in loss of some or all i8259
+		 * interupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
+		 */
+		irq = i8259_irq();
+		if (unlikely(irq < 0))
+			return;
+
+		do_IRQ(irq);
+	}
+
+	if (!(pend & IT_SCSI)) {
+		flags = read_c0_status();
+		clear_c0_status(ST0_IM);
+		do_IRQ(PCIMT_IRQ_SCSI);
+		write_c0_status(flags);
+	}
+}
+
+/*
+ * hwint 3 should deal with the PCI A - D interrupts,
+ */
+static void pcimt_hwint3(void)
+{
+	u8 pend = *(volatile char *)PCIMT_CSITPEND;
+	int irq;
+
+	pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
+	pend ^= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
+	clear_c0_status(IE_IRQ3);
+	irq = PCIMT_IRQ_INT2 + ffs(pend) - 1;
+	do_IRQ(irq);
+	set_c0_status(IE_IRQ3);
+}
+
+static void sni_pcimt_hwint(void)
+{
+	u32 pending = (read_c0_cause() & read_c0_status());
+
+	if (pending & C_IRQ5)
+		do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 7);
+	else if (pending & C_IRQ4)
+		do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 6);
+	else if (pending & C_IRQ3)
+		pcimt_hwint3();
+	else if (pending & C_IRQ1)
+		pcimt_hwint1();
+	else if (pending & C_IRQ0) {
+		pcimt_hwint0();
+	}
+}
+
+void __init sni_pcimt_irq_init(void)
+{
+	int i;
+
+	*(volatile u8 *) PCIMT_IRQSEL = IT_ETH | IT_EISA;
+	mips_cpu_irq_init();
+	/* Actually we've got more interrupts to handle ...  */
+	for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++)
+		set_irq_chip(i, &pcimt_irq_type);
+	sni_hwint = sni_pcimt_hwint;
+	change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3);
+}
+
+void sni_pcimt_init(void)
+{
+	sni_pcimt_resource_init();
+	sni_pcimt_detect();
+	sni_pcimt_sc_init();
+	rtc_mips_get_time = mc146818_get_cmos_time;
+	rtc_mips_set_time = mc146818_set_rtc_mmss;
+	board_time_init = sni_cpu_time_init;
+#ifdef CONFIG_PCI
+	register_pci_controller(&sni_controller);
+#endif
+}
+
+static int __init snirm_pcimt_setup_devinit(void)
+{
+	switch (sni_brd_type) {
+	case SNI_BRD_PCI_MTOWER:
+	case SNI_BRD_PCI_DESKTOP:
+	case SNI_BRD_PCI_MTOWER_CPLUS:
+	        platform_device_register(&pcimt_serial8250_device);
+	        break;
+	}
+
+	return 0;
+}
+
+device_initcall(snirm_pcimt_setup_devinit);
diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c
new file mode 100644
index 0000000..3921096
--- /dev/null
+++ b/arch/mips/sni/pcit.c
@@ -0,0 +1,351 @@
+/*
+ * PCI Tower specific code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/serial_8250.h>
+
+#include <asm/mc146818-time.h>
+#include <asm/sni.h>
+#include <asm/time.h>
+#include <asm/irq_cpu.h>
+
+
+#define PORT(_base,_irq)				\
+	{						\
+		.iobase		= _base,		\
+		.irq		= _irq,			\
+		.uartclk	= 1843200,		\
+		.iotype		= UPIO_PORT,		\
+		.flags		= UPF_BOOT_AUTOCONF,	\
+	}
+
+static struct plat_serial8250_port pcit_data[] = {
+	PORT(0x3f8, 0),
+	PORT(0x2f8, 3),
+	{ },
+};
+
+static struct platform_device pcit_serial8250_device = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= pcit_data,
+	},
+};
+
+static struct plat_serial8250_port pcit_cplus_data[] = {
+	PORT(0x3f8, 4),
+	PORT(0x2f8, 3),
+	PORT(0x3e8, 4),
+	PORT(0x2e8, 3),
+	{ },
+};
+
+static struct platform_device pcit_cplus_serial8250_device = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= pcit_cplus_data,
+	},
+};
+
+static struct resource sni_io_resource = {
+	.start	= 0x00001000UL,
+	.end	= 0x03bfffffUL,
+	.name	= "PCIT IO MEM",
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource pcit_io_resources[] = {
+	{
+		.start	= 0x00,
+		.end	= 0x1f,
+		.name	= "dma1",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	=  0x40,
+		.end	= 0x5f,
+		.name	= "timer",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	=  0x60,
+		.end	= 0x6f,
+		.name	= "keyboard",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	=  0x80,
+		.end	= 0x8f,
+		.name	= "dma page reg",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	=  0xc0,
+		.end	= 0xdf,
+		.name	= "dma2",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	=  0xcfc,
+		.end	= 0xcff,
+		.name	= "PCI config data",
+		.flags	= IORESOURCE_BUSY
+	}
+};
+
+static struct resource sni_mem_resource = {
+	.start	= 0x10000000UL,
+	.end	= 0xffffffffUL,
+	.name	= "PCIT PCI MEM",
+	.flags	= IORESOURCE_MEM
+};
+
+/*
+ * The RM200/RM300 has a few holes in it's PCI/EISA memory address space used
+ * for other purposes.  Be paranoid and allocate all of the before the PCI
+ * code gets a chance to to map anything else there ...
+ *
+ * This leaves the following areas available:
+ *
+ * 0x10000000 - 0x1009ffff (640kB) PCI/EISA/ISA Bus Memory
+ * 0x10100000 - 0x13ffffff ( 15MB) PCI/EISA/ISA Bus Memory
+ * 0x18000000 - 0x1fbfffff (124MB) PCI/EISA Bus Memory
+ * 0x1ff08000 - 0x1ffeffff (816kB) PCI/EISA Bus Memory
+ * 0xa0000000 - 0xffffffff (1.5GB) PCI/EISA Bus Memory
+ */
+static struct resource pcit_mem_resources[] = {
+	{
+		.start	= 0x14000000,
+		.end	= 0x17bfffff,
+		.name	= "PCI IO",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x17c00000,
+		.end	= 0x17ffffff,
+		.name	= "Cache Replacement Area",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x180a0000,
+		.end	= 0x180bffff,
+		.name	= "Video RAM area",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x180c0000,
+		.end	= 0x180fffff,
+		.name	= "ISA Reserved",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x19000000,
+		.end	= 0x1fbfffff,
+		.name	= "PCI MEM",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1fc00000,
+		.end	= 0x1fc7ffff,
+		.name	= "Boot PROM",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1fc80000,
+		.end	= 0x1fcfffff,
+		.name	= "Diag PROM",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1fd00000,
+		.end	= 0x1fdfffff,
+		.name	= "X-Bus",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1fe00000,
+		.end	= 0x1fefffff,
+		.name	= "BIOS map",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1ff00000,
+		.end	= 0x1ff7ffff,
+		.name	= "NVRAM / EEPROM",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1fff0000,
+		.end	= 0x1fffefff,
+		.name	= "MAUI ASIC",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x1ffff000,
+		.end	= 0x1fffffff,
+		.name	= "MP Agent",
+		.flags	= IORESOURCE_BUSY
+	}, {
+		.start	= 0x20000000,
+		.end	= 0x9fffffff,
+		.name	= "Main Memory",
+		.flags	= IORESOURCE_BUSY
+	}
+};
+
+static void __init sni_pcit_resource_init(void)
+{
+	int i;
+
+	/* request I/O space for devices used on all i[345]86 PCs */
+	for (i = 0; i < ARRAY_SIZE(pcit_io_resources); i++)
+		request_resource(&ioport_resource, pcit_io_resources + i);
+
+	/* request mem space for pcimt-specific devices */
+	for (i = 0; i < ARRAY_SIZE(pcit_mem_resources); i++)
+		request_resource(&sni_mem_resource, pcit_mem_resources + i);
+
+	ioport_resource.end = sni_io_resource.end;
+}
+
+
+extern struct pci_ops sni_pcit_ops;
+
+static struct pci_controller sni_pcit_controller = {
+	.pci_ops	= &sni_pcit_ops,
+	.mem_resource	= &sni_mem_resource,
+	.mem_offset	= 0x10000000UL,
+	.io_resource	= &sni_io_resource,
+	.io_offset	= 0x00000000UL
+};
+
+static void enable_pcit_irq(unsigned int irq)
+{
+	u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24);
+
+	*(volatile u32 *)SNI_PCIT_INT_REG |= mask;
+}
+
+void disable_pcit_irq(unsigned int irq)
+{
+	u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24);
+
+	*(volatile u32 *)SNI_PCIT_INT_REG &= ~mask;
+}
+
+void end_pcit_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_pcit_irq(irq);
+}
+
+static struct irq_chip pcit_irq_type = {
+	.typename = "PCIT",
+	.ack = disable_pcit_irq,
+	.mask = disable_pcit_irq,
+	.mask_ack = disable_pcit_irq,
+	.unmask = enable_pcit_irq,
+	.end = end_pcit_irq,
+};
+
+static void pcit_hwint1(void)
+{
+	u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
+	int irq;
+
+	clear_c0_status(IE_IRQ1);
+	irq = ffs((pending >> 16) & 0x7f);
+
+	if (likely(irq > 0))
+		do_IRQ (irq + SNI_PCIT_INT_START - 1);
+	set_c0_status (IE_IRQ1);
+}
+
+static void pcit_hwint0(void)
+{
+	u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
+	int irq;
+
+	clear_c0_status(IE_IRQ0);
+	irq = ffs((pending >> 16) & 0x7f);
+
+	if (likely(irq > 0))
+		do_IRQ (irq + SNI_PCIT_INT_START - 1);
+	set_c0_status (IE_IRQ0);
+}
+
+static void sni_pcit_hwint(void)
+{
+	u32 pending = (read_c0_cause() & read_c0_status());
+
+	if (pending & C_IRQ1)
+		pcit_hwint1();
+	else if (pending & C_IRQ2)
+		do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 4);
+	else if (pending & C_IRQ3)
+		do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 5);
+	else if (pending & C_IRQ5)
+		do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 7);
+}
+
+static void sni_pcit_hwint_cplus(void)
+{
+	u32 pending = (read_c0_cause() & read_c0_status());
+
+	if (pending & C_IRQ0)
+		pcit_hwint0();
+	else if (pending & C_IRQ2)
+		do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 4);
+	else if (pending & C_IRQ3)
+		do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 5);
+	else if (pending & C_IRQ5)
+		do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 7);
+}
+
+void __init sni_pcit_irq_init(void)
+{
+	int i;
+
+	mips_cpu_irq_init();
+	for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
+		set_irq_chip(i, &pcit_irq_type);
+	*(volatile u32 *)SNI_PCIT_INT_REG = 0;
+	sni_hwint = sni_pcit_hwint;
+	change_c0_status(ST0_IM, IE_IRQ1);
+	setup_irq (SNI_PCIT_INT_START + 6, &sni_isa_irq);
+}
+
+void __init sni_pcit_cplus_irq_init(void)
+{
+	int i;
+
+	mips_cpu_irq_init();
+	for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
+		set_irq_chip(i, &pcit_irq_type);
+	*(volatile u32 *)SNI_PCIT_INT_REG = 0;
+	sni_hwint = sni_pcit_hwint_cplus;
+	change_c0_status(ST0_IM, IE_IRQ0);
+	setup_irq (SNI_PCIT_INT_START + 6, &sni_isa_irq);
+}
+
+void sni_pcit_init(void)
+{
+	sni_pcit_resource_init();
+	rtc_mips_get_time = mc146818_get_cmos_time;
+	rtc_mips_set_time = mc146818_set_rtc_mmss;
+	board_time_init = sni_cpu_time_init;
+#ifdef CONFIG_PCI
+	register_pci_controller(&sni_pcit_controller);
+#endif
+}
+
+static int __init snirm_pcit_setup_devinit(void)
+{
+	switch (sni_brd_type) {
+	case SNI_BRD_PCI_TOWER:
+	        platform_device_register(&pcit_serial8250_device);
+	        break;
+
+	case SNI_BRD_PCI_TOWER_CPLUS:
+	        platform_device_register(&pcit_cplus_serial8250_device);
+	        break;
+	}
+	return 0;
+}
+
+device_initcall(snirm_pcit_setup_devinit);
diff --git a/arch/mips/sni/reset.c b/arch/mips/sni/reset.c
index be85bec..2eada8a 100644
--- a/arch/mips/sni/reset.c
+++ b/arch/mips/sni/reset.c
@@ -13,12 +13,11 @@
  * controller to pulse the reset-line low. We try that for a while,
  * and if it doesn't work, we do some other stupid things.
  */
-static inline void
-kb_wait(void)
+static inline void kb_wait(void)
 {
 	int i;
 
-	for (i=0; i<0x10000; i++)
+	for (i = 0; i < 0x10000; i++)
 		if ((inb_p(0x64) & 0x02) == 0)
 			break;
 }
@@ -32,9 +31,9 @@
 	   We can do that easier ...  */
 	local_irq_disable();
 	for (;;) {
-		for (i=0; i<100; i++) {
+		for (i = 0; i < 100; i++) {
 			kb_wait();
-			for(j = 0; j < 100000 ; j++)
+			for (j = 0; j < 100000 ; j++)
 				/* nothing */;
 			outb_p(0xfe,0x64);	 /* pulse reset low */
 		}
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
new file mode 100644
index 0000000..517dc69
--- /dev/null
+++ b/arch/mips/sni/rm200.c
@@ -0,0 +1,186 @@
+/*
+ * RM200 specific code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <asm/sni.h>
+#include <asm/time.h>
+#include <asm/ds1216.h>
+#include <asm/irq_cpu.h>
+
+#define PORT(_base,_irq)				\
+	{						\
+		.iobase		= _base,		\
+		.irq		= _irq,			\
+		.uartclk	= 1843200,		\
+		.iotype		= UPIO_PORT,		\
+		.flags		= UPF_BOOT_AUTOCONF,	\
+	}
+
+static struct plat_serial8250_port rm200_data[] = {
+	PORT(0x3f8, 4),
+	PORT(0x2f8, 3),
+	{ },
+};
+
+static struct platform_device rm200_serial8250_device = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= rm200_data,
+	},
+};
+
+static struct resource snirm_82596_rm200_rsrc[] = {
+	{
+		.start = 0xb8000000,
+		.end   = 0xb80fffff,
+		.flags = IORESOURCE_MEM
+	},
+	{
+		.start = 0xbb000000,
+		.end   = 0xbb000004,
+		.flags = IORESOURCE_MEM
+	},
+	{
+		.start = 0xbff00000,
+		.end   = 0xbff00020,
+		.flags = IORESOURCE_MEM
+	},
+	{
+		.start = 27,
+		.end   = 27,
+		.flags = IORESOURCE_IRQ
+	},
+	{
+		.flags = 0x00
+	}
+};
+
+static struct platform_device snirm_82596_rm200_pdev = {
+	.name           = "snirm_82596",
+	.num_resources  = ARRAY_SIZE(snirm_82596_rm200_rsrc),
+	.resource       = snirm_82596_rm200_rsrc
+};
+
+static struct resource snirm_53c710_rm200_rsrc[] = {
+	{
+		.start = 0xb9000000,
+		.end   = 0xb90fffff,
+		.flags = IORESOURCE_MEM
+	},
+	{
+		.start = 26,
+		.end   = 26,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct platform_device snirm_53c710_rm200_pdev = {
+	.name           = "snirm_53c710",
+	.num_resources  = ARRAY_SIZE(snirm_53c710_rm200_rsrc),
+	.resource       = snirm_53c710_rm200_rsrc
+};
+
+static int __init snirm_setup_devinit(void)
+{
+	if (sni_brd_type == SNI_BRD_RM200) {
+		platform_device_register(&rm200_serial8250_device);
+		platform_device_register(&snirm_82596_rm200_pdev);
+		platform_device_register(&snirm_53c710_rm200_pdev);
+	}
+	return 0;
+}
+
+device_initcall(snirm_setup_devinit);
+
+
+#define SNI_RM200_INT_STAT_REG  0xbc000000
+#define SNI_RM200_INT_ENA_REG   0xbc080000
+
+#define SNI_RM200_INT_START  24
+#define SNI_RM200_INT_END    28
+
+static void enable_rm200_irq(unsigned int irq)
+{
+	unsigned int mask = 1 << (irq - SNI_RM200_INT_START);
+
+	*(volatile u8 *)SNI_RM200_INT_ENA_REG &= ~mask;
+}
+
+void disable_rm200_irq(unsigned int irq)
+{
+	unsigned int mask = 1 << (irq - SNI_RM200_INT_START);
+
+	*(volatile u8 *)SNI_RM200_INT_ENA_REG |= mask;
+}
+
+void end_rm200_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_rm200_irq(irq);
+}
+
+static struct irq_chip rm200_irq_type = {
+	.typename = "RM200",
+	.ack = disable_rm200_irq,
+	.mask = disable_rm200_irq,
+	.mask_ack = disable_rm200_irq,
+	.unmask = enable_rm200_irq,
+	.end = end_rm200_irq,
+};
+
+static void sni_rm200_hwint(void)
+{
+	u32 pending = read_c0_cause() & read_c0_status();
+	u8 mask;
+	u8 stat;
+	int irq;
+
+	if (pending & C_IRQ5)
+		do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 7);
+	else if (pending & C_IRQ0) {
+		clear_c0_status (IE_IRQ0);
+		mask = *(volatile u8 *)SNI_RM200_INT_ENA_REG ^ 0x1f;
+		stat = *(volatile u8 *)SNI_RM200_INT_STAT_REG ^ 0x14;
+		irq = ffs(stat & mask & 0x1f);
+
+		if (likely(irq > 0))
+			do_IRQ (irq + SNI_RM200_INT_START - 1);
+		set_c0_status (IE_IRQ0);
+	}
+}
+
+void __init sni_rm200_irq_init(void)
+{
+	int i;
+
+	* (volatile u8 *)SNI_RM200_INT_ENA_REG = 0x1f;
+
+	mips_cpu_irq_init();
+	/* Actually we've got more interrupts to handle ...  */
+	for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++)
+		set_irq_chip(i, &rm200_irq_type);
+	sni_hwint = sni_rm200_hwint;
+	change_c0_status(ST0_IM, IE_IRQ0);
+	setup_irq (SNI_RM200_INT_START + 0, &sni_isa_irq);
+}
+
+void sni_rm200_init(void)
+{
+	set_io_port_base(SNI_PORT_BASE + 0x02000000);
+	ioport_resource.end += 0x02000000;
+	ds1216_base = (volatile unsigned char *) SNI_DS1216_RM200_BASE;
+	rtc_mips_get_time = ds1216_get_cmos_time;
+	board_time_init = sni_cpu_time_init;
+}
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
index afeb7f1..68d7cf6 100644
--- a/arch/mips/sni/setup.c
+++ b/arch/mips/sni/setup.c
@@ -6,16 +6,10 @@
  * for more details.
  *
  * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
  */
 #include <linux/eisa.h>
-#include <linux/hdreg.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
 #include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/mc146818rtc.h>
-#include <linux/pm.h>
-#include <linux/pci.h>
 #include <linux/console.h>
 #include <linux/fb.h>
 #include <linux/screen_info.h>
@@ -25,52 +19,16 @@
 #include <asm/sgialib.h>
 #endif
 
-#include <asm/bcache.h>
-#include <asm/bootinfo.h>
 #include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mc146818-time.h>
-#include <asm/processor.h>
 #include <asm/reboot.h>
 #include <asm/sni.h>
-#include <asm/time.h>
-#include <asm/traps.h>
+
+unsigned int sni_brd_type;
 
 extern void sni_machine_restart(char *command);
 extern void sni_machine_halt(void);
 extern void sni_machine_power_off(void);
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-	/* set the clock to 100 Hz */
-	outb_p(0x34,0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
-	outb_p(LATCH & 0xff , 0x40);	/* LSB */
-	outb(LATCH >> 8 , 0x40);	/* MSB */
-	setup_irq(0, irq);
-}
-
-/*
- * A bit more gossip about the iron we're running on ...
- */
-static inline void sni_pcimt_detect(void)
-{
-	char boardtype[80];
-	unsigned char csmsr;
-	char *p = boardtype;
-	unsigned int asic;
-
-	csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
-
-	p += sprintf(p, "%s PCI", (csmsr & 0x80) ? "RM200" : "RM300");
-	if ((csmsr & 0x80) == 0)
-		p += sprintf(p, ", board revision %s",
-		             (csmsr & 0x20) ? "D" : "C");
-	asic = csmsr & 0x80;
-	asic = (csmsr & 0x08) ? asic : !asic;
-	p += sprintf(p, ", ASIC PCI Rev %s", asic ? "1.0" : "1.1");
-	printk("%s.\n", boardtype);
-}
-
 static void __init sni_display_setup(void)
 {
 #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) && defined(CONFIG_ARC)
@@ -90,175 +48,11 @@
 #endif
 }
 
-static struct resource sni_io_resource = {
-	.start	= 0x00001000UL,
-	.end	= 0x03bfffffUL,
-	.name	= "PCIMT IO MEM",
-	.flags	= IORESOURCE_IO,
-};
-
-static struct resource pcimt_io_resources[] = {
-	{
-		.start	= 0x00,
-		.end	= 0x1f,
-		.name	= "dma1",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	=  0x40,
-		.end	= 0x5f,
-		.name	= "timer",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	=  0x60,
-		.end	= 0x6f,
-		.name	= "keyboard",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	=  0x80,
-		.end	= 0x8f,
-		.name	= "dma page reg",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	=  0xc0,
-		.end	= 0xdf,
-		.name	= "dma2",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	=  0xcfc,
-		.end	= 0xcff,
-		.name	= "PCI config data",
-		.flags	= IORESOURCE_BUSY
-	}
-};
-
-static struct resource sni_mem_resource = {
-	.start	= 0x10000000UL,
-	.end	= 0xffffffffUL,
-	.name	= "PCIMT PCI MEM",
-	.flags	= IORESOURCE_MEM
-};
-
-/*
- * The RM200/RM300 has a few holes in it's PCI/EISA memory address space used
- * for other purposes.  Be paranoid and allocate all of the before the PCI
- * code gets a chance to to map anything else there ...
- *
- * This leaves the following areas available:
- *
- * 0x10000000 - 0x1009ffff (640kB) PCI/EISA/ISA Bus Memory
- * 0x10100000 - 0x13ffffff ( 15MB) PCI/EISA/ISA Bus Memory
- * 0x18000000 - 0x1fbfffff (124MB) PCI/EISA Bus Memory
- * 0x1ff08000 - 0x1ffeffff (816kB) PCI/EISA Bus Memory
- * 0xa0000000 - 0xffffffff (1.5GB) PCI/EISA Bus Memory
- */
-static struct resource pcimt_mem_resources[] = {
-	{
-		.start	= 0x100a0000,
-		.end	= 0x100bffff,
-		.name	= "Video RAM area",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	= 0x100c0000,
-		.end	= 0x100fffff,
-		.name	= "ISA Reserved",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	= 0x14000000,
-		.end	= 0x17bfffff,
-		.name	= "PCI IO",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	= 0x17c00000,
-		.end	= 0x17ffffff,
-		.name	= "Cache Replacement Area",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	= 0x1a000000,
-		.end	= 0x1a000003,
-		.name	= "PCI INT Acknowledge",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	= 0x1fc00000,
-		.end	= 0x1fc7ffff,
-		.name	= "Boot PROM",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	= 0x1fc80000,
-		.end	= 0x1fcfffff,
-		.name	= "Diag PROM",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	= 0x1fd00000,
-		.end	= 0x1fdfffff,
-		.name	= "X-Bus",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	= 0x1fe00000,
-		.end	= 0x1fefffff,
-		.name	= "BIOS map",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	= 0x1ff00000,
-		.end	= 0x1ff7ffff,
-		.name	= "NVRAM / EEPROM",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	= 0x1fff0000,
-		.end	= 0x1fffefff,
-		.name	= "ASIC PCI",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	= 0x1ffff000,
-		.end	= 0x1fffffff,
-		.name	= "MP Agent",
-		.flags	= IORESOURCE_BUSY
-	}, {
-		.start	= 0x20000000,
-		.end	= 0x9fffffff,
-		.name	= "Main Memory",
-		.flags	= IORESOURCE_BUSY
-	}
-};
-
-static void __init sni_resource_init(void)
-{
-	int i;
-
-	/* request I/O space for devices used on all i[345]86 PCs */
-	for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++)
-		request_resource(&ioport_resource, pcimt_io_resources + i);
-
-	/* request mem space for pcimt-specific devices */
-	for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++)
-		request_resource(&sni_mem_resource, pcimt_mem_resources + i);
-
-	ioport_resource.end = sni_io_resource.end;
-}
-
-extern struct pci_ops sni_pci_ops;
-
-static struct pci_controller sni_controller = {
-	.pci_ops	= &sni_pci_ops,
-	.mem_resource	= &sni_mem_resource,
-	.mem_offset	= 0x10000000UL,
-	.io_resource	= &sni_io_resource,
-	.io_offset	= 0x00000000UL
-};
-
-static inline void sni_pcimt_time_init(void)
-{
-	rtc_mips_get_time = mc146818_get_cmos_time;
-	rtc_mips_set_time = mc146818_set_rtc_mmss;
-}
 
 void __init plat_mem_setup(void)
 {
-	sni_pcimt_detect();
-	sni_pcimt_sc_init();
-	sni_pcimt_time_init();
-
 	set_io_port_base(SNI_PORT_BASE);
-	ioport_resource.end = sni_io_resource.end;
+//	ioport_resource.end = sni_io_resource.end;
 
 	/*
 	 * Setup (E)ISA I/O memory access stuff
@@ -268,15 +62,33 @@
 	EISA_bus = 1;
 #endif
 
-	sni_resource_init();
+	switch (sni_brd_type) {
+	case SNI_BRD_10:
+	case SNI_BRD_10NEW:
+	case SNI_BRD_TOWER_OASIC:
+	case SNI_BRD_MINITOWER:
+	        sni_a20r_init();
+	        break;
+
+	case SNI_BRD_PCI_TOWER:
+	case SNI_BRD_PCI_TOWER_CPLUS:
+	        sni_pcit_init();
+		break;
+
+	case SNI_BRD_RM200:
+	        sni_rm200_init();
+	        break;
+
+	case SNI_BRD_PCI_MTOWER:
+	case SNI_BRD_PCI_DESKTOP:
+	case SNI_BRD_PCI_MTOWER_CPLUS:
+	        sni_pcimt_init();
+	        break;
+	}
 
 	_machine_restart = sni_machine_restart;
 	_machine_halt = sni_machine_halt;
 	pm_power_off = sni_machine_power_off;
 
 	sni_display_setup();
-
-#ifdef CONFIG_PCI
-	register_pci_controller(&sni_controller);
-#endif
 }
diff --git a/arch/mips/sni/sniprom.c b/arch/mips/sni/sniprom.c
index 1213d16..6a44bbf 100644
--- a/arch/mips/sni/sniprom.c
+++ b/arch/mips/sni/sniprom.c
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/string.h>
+#include <linux/console.h>
 
 #include <asm/addrspace.h>
 #include <asm/sni.h>
@@ -31,7 +32,7 @@
 #define PROM_ENTRY(x)		(PROM_VEC + (x))
 
 
-#undef DEBUG
+#define DEBUG
 #ifdef DEBUG
 #define DBG_PRINTF(x...)     prom_printf(x)
 #else
@@ -93,14 +94,14 @@
 {
 	int	i;
 
-	prom_printf("SNI IDProm dump (first 128byte):\n");
-	for(i=0;i<128;i++) {
+	prom_printf("SNI IDProm dump:\n");
+	for (i = 0; i < 256; i++) {
 		if (i%16 == 0)
 			prom_printf("%04x ", i);
 
-		prom_printf("%02x ", *(unsigned char *) (SNI_IDPROM_BASE+i));
+		prom_printf("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i));
 
-		if (i%16 == 15)
+		if (i % 16 == 15)
 			prom_printf("\n");
 	}
 }
@@ -118,7 +119,7 @@
 	} memconf[8];
 
 	/* MemSIZE from prom in 16MByte chunks */
-	memsize=*((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
+	memsize = *((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
 
 	DBG_PRINTF("IDProm memsize: %lu MByte\n", memsize);
 
@@ -126,26 +127,134 @@
 	__prom_get_memconf(&memconf);
 
 	DBG_PRINTF("prom_get_mem_conf memory configuration:\n");
-	for(i=0;i<8 && memconf[i].size;i++) {
-		prom_printf("Bank%d: %08x @ %08x\n", i,
+	for (i = 0;i < 8 && memconf[i].size; i++) {
+		if (sni_brd_type == SNI_BRD_PCI_TOWER ||
+		    sni_brd_type == SNI_BRD_PCI_TOWER_CPLUS) {
+			if (memconf[i].base >= 0x20000000 &&
+			    memconf[i].base <  0x30000000) {
+				memconf[i].base -= 0x20000000;
+			}
+	}
+		DBG_PRINTF("Bank%d: %08x @ %08x\n", i,
 			memconf[i].size, memconf[i].base);
 		add_memory_region(memconf[i].base, memconf[i].size, BOOT_MEM_RAM);
 	}
 }
 
+static void __init sni_console_setup(void)
+{
+	char *ctype;
+	char *cdev;
+	char *baud;
+	int port;
+	static char options[8];
+
+	cdev = prom_getenv ("console_dev");
+	if (strncmp (cdev, "tty", 3) == 0) {
+		ctype = prom_getenv ("console");
+		switch (*ctype) {
+		default:
+		case 'l':
+	                port = 0;
+	                baud = prom_getenv("lbaud");
+	                break;
+		case 'r':
+	                port = 1;
+	                baud = prom_getenv("rbaud");
+	                break;
+		}
+		if (baud)
+			strcpy(options, baud);
+		add_preferred_console("ttyS", port, baud ? options : NULL);
+	}
+}
+
 void __init prom_init(void)
 {
 	int argc = fw_arg0;
 	char **argv = (void *)fw_arg1;
-	unsigned int sni_brd_type = *(unsigned char *) SNI_IDPROM_BRDTYPE;
 	int i;
+	int cputype;
 
-	DBG_PRINTF("Found SNI brdtype %02x\n", sni_brd_type);
+	sni_brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
+	cputype = *(unsigned char *)SNI_IDPROM_CPUTYPE;
+	switch (sni_brd_type) {
+	case SNI_BRD_TOWER_OASIC:
+	        switch (cputype) {
+		case SNI_CPU_M8030:
+		        systype = "RM400-330";
+		        break;
+		case SNI_CPU_M8031:
+		        systype = "RM400-430";
+		        break;
+		case SNI_CPU_M8037:
+		        systype = "RM400-530";
+		        break;
+		case SNI_CPU_M8034:
+		        systype = "RM400-730";
+		        break;
+		default:
+			systype = "RM400-xxx";
+			break;
+		}
+	        break;
+	case SNI_BRD_MINITOWER:
+	        switch (cputype) {
+		case SNI_CPU_M8021:
+		case SNI_CPU_M8043:
+		        systype = "RM400-120";
+		        break;
+		case SNI_CPU_M8040:
+		        systype = "RM400-220";
+		        break;
+		case SNI_CPU_M8053:
+		        systype = "RM400-225";
+		        break;
+		case SNI_CPU_M8050:
+		        systype = "RM400-420";
+		        break;
+		default:
+			systype = "RM400-xxx";
+			break;
+		}
+	        break;
+	case SNI_BRD_PCI_TOWER:
+	        systype = "RM400-Cxx";
+	        break;
+	case SNI_BRD_RM200:
+	        systype = "RM200-xxx";
+	        break;
+	case SNI_BRD_PCI_MTOWER:
+	        systype = "RM300-Cxx";
+	        break;
+	case SNI_BRD_PCI_DESKTOP:
+	        switch (read_c0_prid() & 0xff00) {
+		case PRID_IMP_R4600:
+		case PRID_IMP_R4700:
+		        systype = "RM200-C20";
+		        break;
+		case PRID_IMP_R5000:
+		        systype = "RM200-C40";
+		        break;
+		default:
+		        systype = "RM200-Cxx";
+		        break;
+		}
+	        break;
+	case SNI_BRD_PCI_TOWER_CPLUS:
+	        systype = "RM400-Exx";
+	        break;
+	case SNI_BRD_PCI_MTOWER_CPLUS:
+	        systype = "RM300-Exx";
+	        break;
+	}
+	DBG_PRINTF("Found SNI brdtype %02x name %s\n", sni_brd_type,systype);
 
 #ifdef DEBUG
 	sni_idprom_dump();
 #endif
 	sni_mem_init();
+	sni_console_setup();
 
 	/* copy prom cmdline parameters to kernel cmdline */
 	for (i = 1; i < argc; i++) {
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c
new file mode 100644
index 0000000..20028fc
--- /dev/null
+++ b/arch/mips/sni/time.c
@@ -0,0 +1,148 @@
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+
+#include <asm/sni.h>
+#include <asm/time.h>
+
+#define SNI_CLOCK_TICK_RATE     3686400
+#define SNI_COUNTER2_DIV        64
+#define SNI_COUNTER0_DIV        ((SNI_CLOCK_TICK_RATE / SNI_COUNTER2_DIV) / HZ)
+
+static void sni_a20r_timer_ack(void)
+{
+        *(volatile u8 *)A20R_PT_TIM0_ACK = 0x0; wmb();
+}
+
+/*
+ * a20r platform uses 2 counters to divide the input frequency.
+ * Counter 2 output is connected to Counter 0 & 1 input.
+ */
+static void __init sni_a20r_timer_setup(struct irqaction *irq)
+{
+        *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34; wmb();
+        *(volatile u8 *)(A20R_PT_CLOCK_BASE +  0) = (SNI_COUNTER0_DIV) & 0xff; wmb();
+        *(volatile u8 *)(A20R_PT_CLOCK_BASE +  0) = (SNI_COUNTER0_DIV >> 8) & 0xff; wmb();
+
+        *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4; wmb();
+        *(volatile u8 *)(A20R_PT_CLOCK_BASE +  8) = (SNI_COUNTER2_DIV) & 0xff; wmb();
+        *(volatile u8 *)(A20R_PT_CLOCK_BASE +  8) = (SNI_COUNTER2_DIV >> 8) & 0xff; wmb();
+
+        setup_irq(SNI_A20R_IRQ_TIMER, irq);
+        mips_timer_ack = sni_a20r_timer_ack;
+}
+
+#define SNI_8254_TICK_RATE        1193182UL
+
+#define SNI_8254_TCSAMP_COUNTER   ((SNI_8254_TICK_RATE / HZ) + 255)
+
+static __init unsigned long dosample(void)
+{
+	u32 ct0, ct1;
+	volatile u8 msb, lsb;
+
+	/* Start the counter. */
+	outb_p (0x34, 0x43);
+	outb_p(SNI_8254_TCSAMP_COUNTER & 0xff, 0x40);
+	outb (SNI_8254_TCSAMP_COUNTER >> 8, 0x40);
+
+	/* Get initial counter invariant */
+	ct0 = read_c0_count();
+
+	/* Latch and spin until top byte of counter0 is zero */
+	do {
+		outb (0x00, 0x43);
+		lsb = inb (0x40);
+		msb = inb (0x40);
+		ct1 = read_c0_count();
+	} while (msb);
+
+	/* Stop the counter. */
+	outb (0x38, 0x43);
+	/*
+	 * Return the difference, this is how far the r4k counter increments
+	 * for every 1/HZ seconds. We round off the nearest 1 MHz of master
+	 * clock (= 1000000 / HZ / 2).
+	 */
+	/*return (ct1 - ct0 + (500000/HZ/2)) / (500000/HZ) * (500000/HZ);*/
+	return (ct1 - ct0) / (500000/HZ) * (500000/HZ);
+}
+
+/*
+ * Here we need to calibrate the cycle counter to at least be close.
+ */
+__init void sni_cpu_time_init(void)
+{
+	unsigned long r4k_ticks[3];
+	unsigned long r4k_tick;
+
+	/*
+	 * Figure out the r4k offset, the algorithm is very simple and works in
+	 * _all_ cases as long as the 8254 counter register itself works ok (as
+	 * an interrupt driving timer it does not because of bug, this is why
+	 * we are using the onchip r4k counter/compare register to serve this
+	 * purpose, but for r4k_offset calculation it will work ok for us).
+	 * There are other very complicated ways of performing this calculation
+	 * but this one works just fine so I am not going to futz around. ;-)
+	 */
+	printk(KERN_INFO "Calibrating system timer... ");
+	dosample();	/* Prime cache. */
+	dosample();	/* Prime cache. */
+	/* Zero is NOT an option. */
+	do {
+		r4k_ticks[0] = dosample();
+	} while (!r4k_ticks[0]);
+	do {
+		r4k_ticks[1] = dosample();
+	} while (!r4k_ticks[1]);
+
+	if (r4k_ticks[0] != r4k_ticks[1]) {
+		printk("warning: timer counts differ, retrying... ");
+		r4k_ticks[2] = dosample();
+		if (r4k_ticks[2] == r4k_ticks[0]
+		    || r4k_ticks[2] == r4k_ticks[1])
+			r4k_tick = r4k_ticks[2];
+		else {
+			printk("disagreement, using average... ");
+			r4k_tick = (r4k_ticks[0] + r4k_ticks[1]
+				   + r4k_ticks[2]) / 3;
+		}
+	} else
+		r4k_tick = r4k_ticks[0];
+
+	printk("%d [%d.%04d MHz CPU]\n", (int) r4k_tick,
+		(int) (r4k_tick / (500000 / HZ)),
+		(int) (r4k_tick % (500000 / HZ)));
+
+	mips_hpt_frequency = r4k_tick * HZ;
+}
+
+/*
+ * R4k counter based timer interrupt. Works on RM200-225 and possibly
+ * others but not on RM400
+ */
+static void __init sni_cpu_timer_setup(struct irqaction *irq)
+{
+        setup_irq(SNI_MIPS_IRQ_CPU_TIMER, irq);
+}
+
+void __init plat_timer_setup(struct irqaction *irq)
+{
+	switch (sni_brd_type) {
+	case SNI_BRD_10:
+	case SNI_BRD_10NEW:
+	case SNI_BRD_TOWER_OASIC:
+	case SNI_BRD_MINITOWER:
+	        sni_a20r_timer_setup (irq);
+	        break;
+
+	case SNI_BRD_PCI_TOWER:
+	case SNI_BRD_RM200:
+	case SNI_BRD_PCI_MTOWER:
+	case SNI_BRD_PCI_DESKTOP:
+	case SNI_BRD_PCI_TOWER_CPLUS:
+	case SNI_BRD_PCI_MTOWER_CPLUS:
+	        sni_cpu_timer_setup (irq);
+	        break;
+	}
+}
diff --git a/arch/parisc/kernel/topology.c b/arch/parisc/kernel/topology.c
index 068b20d..d71cb01 100644
--- a/arch/parisc/kernel/topology.c
+++ b/arch/parisc/kernel/topology.c
@@ -1,5 +1,5 @@
 /*
- * arch/parisc/kernel/topology.c - Populate driverfs with topology information
+ * arch/parisc/kernel/topology.c - Populate sysfs with topology information
  *
  * 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
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 340d9be..6dfbd52 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -620,6 +620,15 @@
 	tristate "Firmware flash interface"
 	depends on PPC64 && RTAS_PROC
 
+config PPC_PMI
+	tristate "Support for PMI"
+	depends PPC_IBM_CELL_BLADE
+	help
+	  PMI (Platform Management Interrupt) is a way to
+	  communicate with the BMC (Baseboard Mangement Controller).
+	  It is used in some IBM Cell blades.
+	default m
+
 config MMIO_NVRAM
 	bool
 	default n
diff --git a/arch/powerpc/boot/dts/kuroboxHD.dts b/arch/powerpc/boot/dts/kuroboxHD.dts
index 096e94a..b897918 100644
--- a/arch/powerpc/boot/dts/kuroboxHD.dts
+++ b/arch/powerpc/boot/dts/kuroboxHD.dts
@@ -35,7 +35,6 @@
 
 		PowerPC,603e { /* Really 8241 */
 			linux,phandle = <2100>;
-			linux,boot-cpu;
 			device_type = "cpu";
 			reg = <0>;
 			clock-frequency = <bebc200>;	/* Fixed by bootwrapper */
diff --git a/arch/powerpc/boot/dts/kuroboxHG.dts b/arch/powerpc/boot/dts/kuroboxHG.dts
index d06b0b0..7531027 100644
--- a/arch/powerpc/boot/dts/kuroboxHG.dts
+++ b/arch/powerpc/boot/dts/kuroboxHG.dts
@@ -35,7 +35,6 @@
 
 		PowerPC,603e { /* Really 8241 */
 			linux,phandle = <2100>;
-			linux,boot-cpu;
 			device_type = "cpu";
 			reg = <0>;
 			clock-frequency = <fdad680>;	/* Fixed by bootwrapper */
diff --git a/arch/powerpc/boot/dts/mpc7448hpc2.dts b/arch/powerpc/boot/dts/mpc7448hpc2.dts
index c4d9562..41d0720 100644
--- a/arch/powerpc/boot/dts/mpc7448hpc2.dts
+++ b/arch/powerpc/boot/dts/mpc7448hpc2.dts
@@ -36,7 +36,6 @@
 			bus-frequency = <0>;		// From U-Boot
 			32-bit;
 			linux,phandle = <201>;
-			linux,boot-cpu;
 		};
 	};
 
diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts
index 26b44f7..260b2e4 100644
--- a/arch/powerpc/boot/dts/mpc8272ads.dts
+++ b/arch/powerpc/boot/dts/mpc8272ads.dts
@@ -34,7 +34,6 @@
                        clock-frequency = <0>;
                        32-bit;
                        linux,phandle = <201>;
-                       linux,boot-cpu;
                };
        };
 
diff --git a/arch/powerpc/boot/dts/mpc8313erdb.dts b/arch/powerpc/boot/dts/mpc8313erdb.dts
index 3d2f5a0..6d72190 100644
--- a/arch/powerpc/boot/dts/mpc8313erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8313erdb.dts
@@ -11,7 +11,7 @@
 
 / {
 	model = "MPC8313ERDB";
-	compatible = "MPC83xx";
+	compatible = "MPC8313ERDB", "MPC831xRDB", "MPC83xxRDB";
 	#address-cells = <1>;
 	#size-cells = <1>;
 
@@ -59,7 +59,7 @@
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			interrupts = <e 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			dfsrr;
 		};
 
@@ -68,7 +68,7 @@
 			compatible = "fsl-i2c";
 			reg = <3100 100>;
 			interrupts = <f 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			dfsrr;
 		};
 
@@ -77,7 +77,7 @@
 			compatible = "mpc83xx_spi";
 			reg = <7000 1000>;
 			interrupts = <10 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			mode = <0>;
 		};
 
@@ -88,8 +88,8 @@
 			reg = <23000 1000>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			interrupt-parent = <700>;
-			interrupts = <26 2>;
+			interrupt-parent = < &ipic >;
+			interrupts = <26 8>;
 			phy_type = "utmi_wide";
 		};
 
@@ -99,18 +99,15 @@
 			reg = <24520 20>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			linux,phandle = <24520>;
-			ethernet-phy@1 {
-				linux,phandle = <2452001>;
-				interrupt-parent = <700>;
-				interrupts = <13 2>;
+			phy1: ethernet-phy@1 {
+				interrupt-parent = < &ipic >;
+				interrupts = <13 8>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@4 {
-				linux,phandle = <2452004>;
-				interrupt-parent = <700>;
-				interrupts = <14 2>;
+			phy4: ethernet-phy@4 {
+				interrupt-parent = < &ipic >;
+				interrupts = <14 8>;
 				reg = <4>;
 				device_type = "ethernet-phy";
 			};
@@ -123,8 +120,8 @@
 			reg = <24000 1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <25 8 24 8 23 8>;
-			interrupt-parent = <700>;
-			phy-handle = <2452001>;
+			interrupt-parent = < &ipic >;
+			phy-handle = < &phy1 >;
 		};
 
 		ethernet@25000 {
@@ -134,8 +131,8 @@
 			reg = <25000 1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <22 8 21 8 20 8>;
-			interrupt-parent = <700>;
-			phy-handle = <2452004>;
+			interrupt-parent = < &ipic >;
+			phy-handle = < &phy4 >;
 		};
 
 		serial@4500 {
@@ -144,7 +141,7 @@
 			reg = <4500 100>;
 			clock-frequency = <0>;
 			interrupts = <9 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 		};
 
 		serial@4600 {
@@ -153,7 +150,7 @@
 			reg = <4600 100>;
 			clock-frequency = <0>;
 			interrupts = <a 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 		};
 
 		pci@8500 {
@@ -161,17 +158,17 @@
 			interrupt-map = <
 
 					/* IDSEL 0x0E -mini PCI */
-					 7000 0 0 1 700 12 8
-					 7000 0 0 2 700 12 8
-					 7000 0 0 3 700 12 8
-					 7000 0 0 4 700 12 8
+					 7000 0 0 1 &ipic 12 8
+					 7000 0 0 2 &ipic 12 8
+					 7000 0 0 3 &ipic 12 8
+					 7000 0 0 4 &ipic 12 8
 
 					/* IDSEL 0x0F - PCI slot */
-					 7800 0 0 1 700 11 8
-					 7800 0 0 2 700 12 8
-					 7800 0 0 3 700 11 8
-					 7800 0 0 4 700 12 8>;
-			interrupt-parent = <700>;
+					 7800 0 0 1 &ipic 11 8
+					 7800 0 0 2 &ipic 12 8
+					 7800 0 0 3 &ipic 11 8
+					 7800 0 0 4 &ipic 12 8>;
+			interrupt-parent = < &ipic >;
 			interrupts = <42 8>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 90000000 90000000 0 10000000
@@ -192,7 +189,7 @@
 			compatible = "talitos";
 			reg = <30000 7000>;
 			interrupts = <b 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			/* Rev. 2.2 */
 			num-channels = <1>;
 			channel-fifo-len = <18>;
@@ -206,8 +203,7 @@
 		 * sense == 8: Level, low assertion
 		 * sense == 2: Edge, high-to-low change
 		 */
-		pic@700 {
-			linux,phandle = <700>;
+		ipic: pic@700 {
 			interrupt-controller;
 			#address-cells = <0>;
 			#interrupt-cells = <2>;
diff --git a/arch/powerpc/boot/dts/mpc8323emds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
similarity index 77%
rename from arch/powerpc/boot/dts/mpc8323emds.dts
rename to arch/powerpc/boot/dts/mpc832x_mds.dts
index fa7ef24..06b3106 100644
--- a/arch/powerpc/boot/dts/mpc8323emds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -11,16 +11,14 @@
 
 / {
 	model = "MPC8323EMDS";
-	compatible = "MPC83xx";
+	compatible = "MPC8323EMDS", "MPC832xMDS", "MPC83xxMDS";
 	#address-cells = <1>;
 	#size-cells = <1>;
-	linux,phandle = <100>;
 
 	cpus {
 		#cpus = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		linux,phandle = <200>;
 
 		PowerPC,8323@0 {
 			device_type = "cpu";
@@ -33,14 +31,11 @@
 			bus-frequency = <0>;
 			clock-frequency = <0>;
 			32-bit;
-			linux,phandle = <201>;
-			linux,boot-cpu;
 		};
 	};
 
 	memory {
 		device_type = "memory";
-		linux,phandle = <300>;
 		reg = <00000000 08000000>;
 	};
 
@@ -69,7 +64,7 @@
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			interrupts = <e 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			dfsrr;
 		};
 
@@ -79,7 +74,7 @@
 			reg = <4500 100>;
 			clock-frequency = <0>;
 			interrupts = <9 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 		};
 
 		serial@4600 {
@@ -88,7 +83,7 @@
 			reg = <4600 100>;
 			clock-frequency = <0>;
 			interrupts = <a 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 		};
 
 		crypto@30000 {
@@ -97,7 +92,7 @@
 			compatible = "talitos";
 			reg = <30000 7000>;
 			interrupts = <b 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			/* Rev. 2.2 */
 			num-channels = <1>;
 			channel-fifo-len = <18>;
@@ -106,51 +101,50 @@
 		};
 
 		pci@8500 {
-			linux,phandle = <8500>;
 			interrupt-map-mask = <f800 0 0 7>;
 			interrupt-map = <
 					/* IDSEL 0x11 AD17 */
-					 8800 0 0 1 700 14 8
-					 8800 0 0 2 700 15 8
-					 8800 0 0 3 700 16 8
-					 8800 0 0 4 700 17 8
+					 8800 0 0 1 &ipic 14 8
+					 8800 0 0 2 &ipic 15 8
+					 8800 0 0 3 &ipic 16 8
+					 8800 0 0 4 &ipic 17 8
 
 					/* IDSEL 0x12 AD18 */
-					 9000 0 0 1 700 16 8
-					 9000 0 0 2 700 17 8
-					 9000 0 0 3 700 14 8
-					 9000 0 0 4 700 15 8
+					 9000 0 0 1 &ipic 16 8
+					 9000 0 0 2 &ipic 17 8
+					 9000 0 0 3 &ipic 14 8
+					 9000 0 0 4 &ipic 15 8
 
 					/* IDSEL 0x13 AD19 */
-					 9800 0 0 1 700 17 8
-					 9800 0 0 2 700 14 8
-					 9800 0 0 3 700 15 8
-					 9800 0 0 4 700 16 8
+					 9800 0 0 1 &ipic 17 8
+					 9800 0 0 2 &ipic 14 8
+					 9800 0 0 3 &ipic 15 8
+					 9800 0 0 4 &ipic 16 8
 
 					/* IDSEL 0x15 AD21*/
-					 a800 0 0 1 700 14 8
-					 a800 0 0 2 700 15 8
-					 a800 0 0 3 700 16 8
-					 a800 0 0 4 700 17 8
+					 a800 0 0 1 &ipic 14 8
+					 a800 0 0 2 &ipic 15 8
+					 a800 0 0 3 &ipic 16 8
+					 a800 0 0 4 &ipic 17 8
 
 					/* IDSEL 0x16 AD22*/
-					 b000 0 0 1 700 17 8
-					 b000 0 0 2 700 14 8
-					 b000 0 0 3 700 15 8
-					 b000 0 0 4 700 16 8
+					 b000 0 0 1 &ipic 17 8
+					 b000 0 0 2 &ipic 14 8
+					 b000 0 0 3 &ipic 15 8
+					 b000 0 0 4 &ipic 16 8
 
 					/* IDSEL 0x17 AD23*/
-					 b800 0 0 1 700 16 8
-					 b800 0 0 2 700 17 8
-					 b800 0 0 3 700 14 8
-					 b800 0 0 4 700 15 8
+					 b800 0 0 1 &ipic 16 8
+					 b800 0 0 2 &ipic 17 8
+					 b800 0 0 3 &ipic 14 8
+					 b800 0 0 4 &ipic 15 8
 
 					/* IDSEL 0x18 AD24*/
-					 c000 0 0 1 700 15 8
-					 c000 0 0 2 700 16 8
-					 c000 0 0 3 700 17 8
-					 c000 0 0 4 700 14 8>;
-			interrupt-parent = <700>;
+					 c000 0 0 1 &ipic 15 8
+					 c000 0 0 2 &ipic 16 8
+					 c000 0 0 3 &ipic 17 8
+					 c000 0 0 4 &ipic 14 8>;
+			interrupt-parent = < &ipic >;
 			interrupts = <42 8>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 a0000000 90000000 0 10000000
@@ -165,8 +159,7 @@
 			device_type = "pci";
 		};
 
-		pic@700 {
-			linux,phandle = <700>;
+		ipic: pic@700 {
 			interrupt-controller;
 			#address-cells = <0>;
 			#interrupt-cells = <2>;
@@ -180,8 +173,7 @@
 			device_type = "par_io";
 			num-ports = <7>;
 
-			ucc_pin@03 {
-				linux,phandle = <140003>;
+			pio3: ucc_pin@03 {
 				pio-map = <
 			/* port  pin  dir  open_drain  assignment  has_irq */
 					3  4  3  0  2  0  /* MDIO */
@@ -204,8 +196,7 @@
 					1  c  1  0  1  0 	/* TX_EN */
 					1  d  2  0  1  0>;/* CRS */
 			};
-			ucc_pin@04 {
-				linux,phandle = <140004>;
+			pio4: ucc_pin@04 {
 				pio-map = <
 			/* port  pin  dir  open_drain  assignment  has_irq */
 					3 1f  2  0  1  0 	/* RX_CLK (CLK7) */
@@ -252,7 +243,7 @@
 			compatible = "fsl_spi";
 			reg = <4c0 40>;
 			interrupts = <2>;
-			interrupt-parent = <80>;
+			interrupt-parent = < &qeic >;
 			mode = "cpu";
 		};
 
@@ -261,7 +252,7 @@
 			compatible = "fsl_spi";
 			reg = <500 40>;
 			interrupts = <1>;
-			interrupt-parent = <80>;
+			interrupt-parent = < &qeic >;
 			mode = "cpu";
 		};
 
@@ -270,7 +261,7 @@
 			compatible = "qe_udc";
 			reg = <6c0 40 8B00 100>;
 			interrupts = <b>;
-			interrupt-parent = <80>;
+			interrupt-parent = < &qeic >;
 			mode = "slave";
 		};
 
@@ -281,12 +272,12 @@
 			device-id = <3>;
 			reg = <2200 200>;
 			interrupts = <22>;
-			interrupt-parent = <80>;
+			interrupt-parent = < &qeic >;
 			mac-address = [ 00 04 9f 00 23 23 ];
 			rx-clock = <19>;
 			tx-clock = <1a>;
-			phy-handle = <212003>;
-			pio-handle = <140003>;
+			phy-handle = < &phy3 >;
+			pio-handle = < &pio3 >;
 		};
 
 		ucc@3200 {
@@ -296,12 +287,12 @@
 			device-id = <4>;
 			reg = <3000 200>;
 			interrupts = <23>;
-			interrupt-parent = <80>;
+			interrupt-parent = < &qeic >;
 			mac-address = [ 00 11 22 33 44 55 ];
 			rx-clock = <17>;
 			tx-clock = <18>;
-			phy-handle = <212004>;
-			pio-handle = <140004>;
+			phy-handle = < &phy4 >;
+			pio-handle = < &pio4 >;
 		};
 
 		mdio@2320 {
@@ -311,26 +302,23 @@
 			device_type = "mdio";
 			compatible = "ucc_geth_phy";
 
-			ethernet-phy@03 {
-				linux,phandle = <212003>;
-				interrupt-parent = <700>;
-				interrupts = <11 2>;
+			phy3: ethernet-phy@03 {
+				interrupt-parent = < &ipic >;
+				interrupts = <11 8>;
 				reg = <3>;
 				device_type = "ethernet-phy";
 				interface = <3>; //ENET_100_MII
 			};
-			ethernet-phy@04 {
-				linux,phandle = <212004>;
-				interrupt-parent = <700>;
-				interrupts = <12 2>;
+			phy4: ethernet-phy@04 {
+				interrupt-parent = < &ipic >;
+				interrupts = <12 8>;
 				reg = <4>;
 				device_type = "ethernet-phy";
 				interface = <3>;
 			};
 		};
 
-		qeic@80 {
-			linux,phandle = <80>;
+		qeic: qeic@80 {
 			interrupt-controller;
 			device_type = "qeic";
 			#address-cells = <0>;
@@ -339,7 +327,7 @@
 			built-in;
 			big-endian;
 			interrupts = <20 8 21 8>; //high:32 low:33
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 		};
 	};
 };
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts
index 27807fc..61b550b 100644
--- a/arch/powerpc/boot/dts/mpc8349emitx.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitx.dts
@@ -10,7 +10,7 @@
  */
 / {
 	model = "MPC8349EMITX";
-	compatible = "MPC834xMITX";
+	compatible = "MPC8349EMITX", "MPC834xMITX", "MPC83xxMITX";
 	#address-cells = <1>;
 	#size-cells = <1>;
 
@@ -58,7 +58,7 @@
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			interrupts = <e 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			dfsrr;
 		};
 
@@ -67,7 +67,7 @@
 			compatible = "fsl-i2c";
 			reg = <3100 100>;
 			interrupts = <f 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			dfsrr;
 		};
 
@@ -76,7 +76,7 @@
 			compatible = "mpc83xx_spi";
 			reg = <7000 1000>;
 			interrupts = <10 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			mode = <0>;
 		};
 
@@ -86,8 +86,8 @@
 			reg = <22000 1000>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			interrupt-parent = <700>;
-			interrupts = <27 2>;
+			interrupt-parent = < &ipic >;
+			interrupts = <27 8>;
 			phy_type = "ulpi";
 			port1;
 		};
@@ -98,8 +98,8 @@
 			reg = <23000 1000>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			interrupt-parent = <700>;
-			interrupts = <26 2>;
+			interrupt-parent = < &ipic >;
+			interrupts = <26 8>;
 			phy_type = "ulpi";
 		};
 
@@ -109,22 +109,19 @@
 			reg = <24520 20>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			linux,phandle = <24520>;
 
 			/* Vitesse 8201 */
-			ethernet-phy@1c {
-				linux,phandle = <245201c>;
-				interrupt-parent = <700>;
-				interrupts = <12 2>;
+			phy1c: ethernet-phy@1c {
+				interrupt-parent = < &ipic >;
+				interrupts = <12 8>;
 				reg = <1c>;
 				device_type = "ethernet-phy";
 			};
 
 			/* Vitesse 7385 */
-			ethernet-phy@1f {
-				linux,phandle = <245201f>;
-				interrupt-parent = <700>;
-				interrupts = <12 2>;
+			phy1f: ethernet-phy@1f {
+				interrupt-parent = < &ipic >;
+				interrupts = <12 8>;
 				reg = <1f>;
 				device_type = "ethernet-phy";
 			};
@@ -138,8 +135,8 @@
 			address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <20 8 21 8 22 8>;
-			interrupt-parent = <700>;
-			phy-handle = <245201c>;
+			interrupt-parent = < &ipic >;
+			phy-handle = < &phy1c >;
 		};
 
 		ethernet@25000 {
@@ -152,8 +149,8 @@
 			address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <23 8 24 8 25 8>;
-			interrupt-parent = <700>;
-			phy-handle = <245201f>;
+			interrupt-parent = < &ipic >;
+			phy-handle = < &phy1f >;
 		};
 
 		serial@4500 {
@@ -162,7 +159,7 @@
 			reg = <4500 100>;
 			clock-frequency = <0>;		// from bootloader
 			interrupts = <9 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 		};
 
 		serial@4600 {
@@ -171,16 +168,16 @@
 			reg = <4600 100>;
 			clock-frequency = <0>;		// from bootloader
 			interrupts = <a 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 		};
 
 		pci@8500 {
 			interrupt-map-mask = <f800 0 0 7>;
 			interrupt-map = <
 					/* IDSEL 0x10 - SATA */
-					8000 0 0 1 700 16 8 /* SATA_INTA */
+					8000 0 0 1 &ipic 16 8 /* SATA_INTA */
 					>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			interrupts = <42 8>;
 			bus-range = <0 0>;
 			ranges = <42000000 0 80000000 80000000 0 10000000
@@ -199,13 +196,13 @@
 			interrupt-map-mask = <f800 0 0 7>;
 			interrupt-map = <
 					/* IDSEL 0x0E - MiniPCI Slot */
-					7000 0 0 1 700 15 8 /* PCI_INTA */
+					7000 0 0 1 &ipic 15 8 /* PCI_INTA */
 
 					/* IDSEL 0x0F - PCI Slot */
-					7800 0 0 1 700 14 8 /* PCI_INTA */
-					7800 0 0 2 700 15 8 /* PCI_INTB */
+					7800 0 0 1 &ipic 14 8 /* PCI_INTA */
+					7800 0 0 2 &ipic 15 8 /* PCI_INTB */
 					 >;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			interrupts = <43 8>;
 			bus-range = <1 1>;
 			ranges = <42000000 0 a0000000 a0000000 0 10000000
@@ -226,15 +223,14 @@
 			compatible = "talitos";
 			reg = <30000 10000>;
 			interrupts = <b 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			num-channels = <4>;
 			channel-fifo-len = <18>;
 			exec-units-mask = <0000007e>;
 			descriptor-types-mask = <01010ebf>;
 		};
 
-		pic@700 {
-			linux,phandle = <700>;
+		ipic: pic@700 {
 			interrupt-controller;
 			#address-cells = <0>;
 			#interrupt-cells = <2>;
diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
index 3190774..b2e1a5e 100644
--- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
@@ -10,7 +10,7 @@
  */
 / {
 	model = "MPC8349EMITXGP";
-	compatible = "MPC834xMITXGP";
+	compatible = "MPC8349EMITXGP", "MPC834xMITX", "MPC83xxMITX";
 	#address-cells = <1>;
 	#size-cells = <1>;
 
@@ -58,7 +58,7 @@
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			interrupts = <e 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			dfsrr;
 		};
 
@@ -67,7 +67,7 @@
 			compatible = "fsl-i2c";
 			reg = <3100 100>;
 			interrupts = <f 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			dfsrr;
 		};
 
@@ -76,7 +76,7 @@
 			compatible = "mpc83xx_spi";
 			reg = <7000 1000>;
 			interrupts = <10 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			mode = <0>;
 		};
 
@@ -86,8 +86,8 @@
 			reg = <23000 1000>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			interrupt-parent = <700>;
-			interrupts = <26 2>;
+			interrupt-parent = < &ipic >;
+			interrupts = <26 8>;
 			dr_mode = "otg";
 			phy_type = "ulpi";
 		};
@@ -98,13 +98,11 @@
 			reg = <24520 20>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			linux,phandle = <24520>;
 
 			/* Vitesse 8201 */
-			ethernet-phy@1c {
-				linux,phandle = <245201c>;
-				interrupt-parent = <700>;
-				interrupts = <12 2>;
+			phy1c: ethernet-phy@1c {
+				interrupt-parent = < &ipic >;
+				interrupts = <12 8>;
 				reg = <1c>;
 				device_type = "ethernet-phy";
 			};
@@ -117,8 +115,8 @@
 			reg = <24000 1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <20 8 21 8 22 8>;
-			interrupt-parent = <700>;
-			phy-handle = <245201c>;
+			interrupt-parent = < &ipic >;
+			phy-handle = < &phy1c >;
 		};
 
 		serial@4500 {
@@ -127,7 +125,7 @@
 			reg = <4500 100>;
 			clock-frequency = <0>;		// from bootloader
 			interrupts = <9 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 		};
 
 		serial@4600 {
@@ -136,17 +134,17 @@
 			reg = <4600 100>;
 			clock-frequency = <0>;		// from bootloader
 			interrupts = <a 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 		};
 
 		pci@8600 {
 			interrupt-map-mask = <f800 0 0 7>;
 			interrupt-map = <
 					/* IDSEL 0x0F - PCI Slot */
-					7800 0 0 1 700 14 8 /* PCI_INTA */
-					7800 0 0 2 700 15 8 /* PCI_INTB */
+					7800 0 0 1 &ipic 14 8 /* PCI_INTA */
+					7800 0 0 2 &ipic 15 8 /* PCI_INTB */
 					 >;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			interrupts = <43 8>;
 			bus-range = <1 1>;
 			ranges = <42000000 0 a0000000 a0000000 0 10000000
@@ -167,15 +165,14 @@
 			compatible = "talitos";
 			reg = <30000 10000>;
 			interrupts = <b 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			num-channels = <4>;
 			channel-fifo-len = <18>;
 			exec-units-mask = <0000007e>;
 			descriptor-types-mask = <01010ebf>;
 		};
 
-		pic@700 {
-			linux,phandle = <700>;
+		ipic: pic@700 {
 			interrupt-controller;
 			#address-cells = <0>;
 			#interrupt-cells = <2>;
diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts
index dc121b3..e4b43c2 100644
--- a/arch/powerpc/boot/dts/mpc834x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc834x_mds.dts
@@ -11,7 +11,7 @@
 
 / {
 	model = "MPC8349EMDS";
-	compatible = "MPC834xMDS";
+	compatible = "MPC8349EMDS", "MPC834xMDS", "MPC83xxMDS";
 	#address-cells = <1>;
 	#size-cells = <1>;
 
@@ -64,7 +64,7 @@
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			interrupts = <e 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			dfsrr;
 		};
 
@@ -73,7 +73,7 @@
 			compatible = "fsl-i2c";
 			reg = <3100 100>;
 			interrupts = <f 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			dfsrr;
 		};
 
@@ -82,7 +82,7 @@
 			compatible = "mpc83xx_spi";
 			reg = <7000 1000>;
 			interrupts = <10 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			mode = <0>;
 		};
 
@@ -94,8 +94,8 @@
 			reg = <22000 1000>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			interrupt-parent = <700>;
-			interrupts = <27 2>;
+			interrupt-parent = < &ipic >;
+			interrupts = <27 8>;
 			phy_type = "ulpi";
 			port1;
 		};
@@ -106,8 +106,8 @@
 			reg = <23000 1000>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			interrupt-parent = <700>;
-			interrupts = <26 2>;
+			interrupt-parent = < &ipic >;
+			interrupts = <26 8>;
 			dr_mode = "otg";
 			phy_type = "ulpi";
 		};
@@ -118,18 +118,15 @@
 			reg = <24520 20>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			linux,phandle = <24520>;
-			ethernet-phy@0 {
-				linux,phandle = <2452000>;
-				interrupt-parent = <700>;
-				interrupts = <11 2>;
+			phy0: ethernet-phy@0 {
+				interrupt-parent = < &ipic >;
+				interrupts = <11 8>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@1 {
-				linux,phandle = <2452001>;
-				interrupt-parent = <700>;
-				interrupts = <12 2>;
+			phy1: ethernet-phy@1 {
+				interrupt-parent = < &ipic >;
+				interrupts = <12 8>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 			};
@@ -143,8 +140,8 @@
 			address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <20 8 21 8 22 8>;
-			interrupt-parent = <700>;
-			phy-handle = <2452000>;
+			interrupt-parent = < &ipic >;
+			phy-handle = < &phy0 >;
 		};
 
 		ethernet@25000 {
@@ -157,8 +154,8 @@
 			address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <23 8 24 8 25 8>;
-			interrupt-parent = <700>;
-			phy-handle = <2452001>;
+			interrupt-parent = < &ipic >;
+			phy-handle = < &phy1 >;
 		};
 
 		serial@4500 {
@@ -167,7 +164,7 @@
 			reg = <4500 100>;
 			clock-frequency = <0>;
 			interrupts = <9 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 		};
 
 		serial@4600 {
@@ -176,7 +173,7 @@
 			reg = <4600 100>;
 			clock-frequency = <0>;
 			interrupts = <a 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 		};
 
 		pci@8500 {
@@ -184,47 +181,47 @@
 			interrupt-map = <
 
 					/* IDSEL 0x11 */
-					 8800 0 0 1 700 14 8
-					 8800 0 0 2 700 15 8
-					 8800 0 0 3 700 16 8
-					 8800 0 0 4 700 17 8
+					 8800 0 0 1 &ipic 14 8
+					 8800 0 0 2 &ipic 15 8
+					 8800 0 0 3 &ipic 16 8
+					 8800 0 0 4 &ipic 17 8
 
 					/* IDSEL 0x12 */
-					 9000 0 0 1 700 16 8
-					 9000 0 0 2 700 17 8
-					 9000 0 0 3 700 14 8
-					 9000 0 0 4 700 15 8
+					 9000 0 0 1 &ipic 16 8
+					 9000 0 0 2 &ipic 17 8
+					 9000 0 0 3 &ipic 14 8
+					 9000 0 0 4 &ipic 15 8
 
 					/* IDSEL 0x13 */
-					 9800 0 0 1 700 17 8
-					 9800 0 0 2 700 14 8
-					 9800 0 0 3 700 15 8
-					 9800 0 0 4 700 16 8
+					 9800 0 0 1 &ipic 17 8
+					 9800 0 0 2 &ipic 14 8
+					 9800 0 0 3 &ipic 15 8
+					 9800 0 0 4 &ipic 16 8
 
 					/* IDSEL 0x15 */
-					 a800 0 0 1 700 14 8
-					 a800 0 0 2 700 15 8
-					 a800 0 0 3 700 16 8
-					 a800 0 0 4 700 17 8
+					 a800 0 0 1 &ipic 14 8
+					 a800 0 0 2 &ipic 15 8
+					 a800 0 0 3 &ipic 16 8
+					 a800 0 0 4 &ipic 17 8
 
 					/* IDSEL 0x16 */
-					 b000 0 0 1 700 17 8
-					 b000 0 0 2 700 14 8
-					 b000 0 0 3 700 15 8
-					 b000 0 0 4 700 16 8
+					 b000 0 0 1 &ipic 17 8
+					 b000 0 0 2 &ipic 14 8
+					 b000 0 0 3 &ipic 15 8
+					 b000 0 0 4 &ipic 16 8
 
 					/* IDSEL 0x17 */
-					 b800 0 0 1 700 16 8
-					 b800 0 0 2 700 17 8
-					 b800 0 0 3 700 14 8
-					 b800 0 0 4 700 15 8
+					 b800 0 0 1 &ipic 16 8
+					 b800 0 0 2 &ipic 17 8
+					 b800 0 0 3 &ipic 14 8
+					 b800 0 0 4 &ipic 15 8
 
 					/* IDSEL 0x18 */
-					 c000 0 0 1 700 15 8
-					 c000 0 0 2 700 16 8
-					 c000 0 0 3 700 17 8
-					 c000 0 0 4 700 14 8>;
-			interrupt-parent = <700>;
+					 c000 0 0 1 &ipic 15 8
+					 c000 0 0 2 &ipic 16 8
+					 c000 0 0 3 &ipic 17 8
+					 c000 0 0 4 &ipic 14 8>;
+			interrupt-parent = < &ipic >;
 			interrupts = <42 8>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 a0000000 a0000000 0 10000000
@@ -244,47 +241,47 @@
 			interrupt-map = <
 
 					/* IDSEL 0x11 */
-					 8800 0 0 1 700 14 8
-					 8800 0 0 2 700 15 8
-					 8800 0 0 3 700 16 8
-					 8800 0 0 4 700 17 8
+					 8800 0 0 1 &ipic 14 8
+					 8800 0 0 2 &ipic 15 8
+					 8800 0 0 3 &ipic 16 8
+					 8800 0 0 4 &ipic 17 8
 
 					/* IDSEL 0x12 */
-					 9000 0 0 1 700 16 8
-					 9000 0 0 2 700 17 8
-					 9000 0 0 3 700 14 8
-					 9000 0 0 4 700 15 8
+					 9000 0 0 1 &ipic 16 8
+					 9000 0 0 2 &ipic 17 8
+					 9000 0 0 3 &ipic 14 8
+					 9000 0 0 4 &ipic 15 8
 
 					/* IDSEL 0x13 */
-					 9800 0 0 1 700 17 8
-					 9800 0 0 2 700 14 8
-					 9800 0 0 3 700 15 8
-					 9800 0 0 4 700 16 8
+					 9800 0 0 1 &ipic 17 8
+					 9800 0 0 2 &ipic 14 8
+					 9800 0 0 3 &ipic 15 8
+					 9800 0 0 4 &ipic 16 8
 
 					/* IDSEL 0x15 */
-					 a800 0 0 1 700 14 8
-					 a800 0 0 2 700 15 8
-					 a800 0 0 3 700 16 8
-					 a800 0 0 4 700 17 8
+					 a800 0 0 1 &ipic 14 8
+					 a800 0 0 2 &ipic 15 8
+					 a800 0 0 3 &ipic 16 8
+					 a800 0 0 4 &ipic 17 8
 
 					/* IDSEL 0x16 */
-					 b000 0 0 1 700 17 8
-					 b000 0 0 2 700 14 8
-					 b000 0 0 3 700 15 8
-					 b000 0 0 4 700 16 8
+					 b000 0 0 1 &ipic 17 8
+					 b000 0 0 2 &ipic 14 8
+					 b000 0 0 3 &ipic 15 8
+					 b000 0 0 4 &ipic 16 8
 
 					/* IDSEL 0x17 */
-					 b800 0 0 1 700 16 8
-					 b800 0 0 2 700 17 8
-					 b800 0 0 3 700 14 8
-					 b800 0 0 4 700 15 8
+					 b800 0 0 1 &ipic 16 8
+					 b800 0 0 2 &ipic 17 8
+					 b800 0 0 3 &ipic 14 8
+					 b800 0 0 4 &ipic 15 8
 
 					/* IDSEL 0x18 */
-					 c000 0 0 1 700 15 8
-					 c000 0 0 2 700 16 8
-					 c000 0 0 3 700 17 8
-					 c000 0 0 4 700 14 8>;
-			interrupt-parent = <700>;
+					 c000 0 0 1 &ipic 15 8
+					 c000 0 0 2 &ipic 16 8
+					 c000 0 0 3 &ipic 17 8
+					 c000 0 0 4 &ipic 14 8>;
+			interrupt-parent = < &ipic >;
 			interrupts = <42 8>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 b0000000 b0000000 0 10000000
@@ -306,7 +303,7 @@
 			compatible = "talitos";
 			reg = <30000 10000>;
 			interrupts = <b 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			num-channels = <4>;
 			channel-fifo-len = <18>;
 			exec-units-mask = <0000007e>;
@@ -321,8 +318,7 @@
 		 * sense == 8: Level, low assertion
 		 * sense == 2: Edge, high-to-low change
 		 */
-		pic@700 {
-			linux,phandle = <700>;
+		ipic: pic@700 {
 			interrupt-controller;
 			#address-cells = <0>;
 			#interrupt-cells = <2>;
diff --git a/arch/powerpc/boot/dts/mpc8360emds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
similarity index 79%
rename from arch/powerpc/boot/dts/mpc8360emds.dts
rename to arch/powerpc/boot/dts/mpc836x_mds.dts
index 9022192..4fe45c0 100644
--- a/arch/powerpc/boot/dts/mpc8360emds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -15,17 +15,15 @@
 */
 
 / {
-	model = "MPC8360EPB";
-	compatible = "MPC83xx";
+	model = "MPC8360MDS";
+	compatible = "MPC8360EMDS", "MPC836xMDS", "MPC83xxMDS";
 	#address-cells = <1>;
 	#size-cells = <1>;
-	linux,phandle = <100>;
 
 	cpus {
 		#cpus = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		linux,phandle = <200>;
 
 		PowerPC,8360@0 {
 			device_type = "cpu";
@@ -38,14 +36,11 @@
 			bus-frequency = <FBC5200>;
 			clock-frequency = <1F78A400>;
 			32-bit;
-			linux,phandle = <201>;
-			linux,boot-cpu;
 		};
 	};
 
 	memory {
 		device_type = "memory";
-		linux,phandle = <300>;
 		reg = <00000000 10000000>;
 	};
 
@@ -74,7 +69,7 @@
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			interrupts = <e 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			dfsrr;
 		};
 
@@ -83,7 +78,7 @@
 			compatible = "fsl-i2c";
 			reg = <3100 100>;
 			interrupts = <f 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			dfsrr;
 		};
 
@@ -93,7 +88,7 @@
 			reg = <4500 100>;
 			clock-frequency = <FBC5200>;
 			interrupts = <9 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 		};
 
 		serial@4600 {
@@ -102,7 +97,7 @@
 			reg = <4600 100>;
 			clock-frequency = <FBC5200>;
 			interrupts = <a 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 		};
 
 		crypto@30000 {
@@ -111,7 +106,7 @@
 			compatible = "talitos";
 			reg = <30000 10000>;
 			interrupts = <b 8>;
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 			num-channels = <4>;
 			channel-fifo-len = <18>;
 			exec-units-mask = <0000007e>;
@@ -120,52 +115,51 @@
 		};
 
 		pci@8500 {
-			linux,phandle = <8500>;
 			interrupt-map-mask = <f800 0 0 7>;
 			interrupt-map = <
 
 					/* IDSEL 0x11 AD17 */
-					 8800 0 0 1 700 14 8
-					 8800 0 0 2 700 15 8
-					 8800 0 0 3 700 16 8
-					 8800 0 0 4 700 17 8
+					 8800 0 0 1 &ipic 14 8
+					 8800 0 0 2 &ipic 15 8
+					 8800 0 0 3 &ipic 16 8
+					 8800 0 0 4 &ipic 17 8
 
 					/* IDSEL 0x12 AD18 */
-					 9000 0 0 1 700 16 8
-					 9000 0 0 2 700 17 8
-					 9000 0 0 3 700 14 8
-					 9000 0 0 4 700 15 8
+					 9000 0 0 1 &ipic 16 8
+					 9000 0 0 2 &ipic 17 8
+					 9000 0 0 3 &ipic 14 8
+					 9000 0 0 4 &ipic 15 8
 
 					/* IDSEL 0x13 AD19 */
-					 9800 0 0 1 700 17 8
-					 9800 0 0 2 700 14 8
-					 9800 0 0 3 700 15 8
-					 9800 0 0 4 700 16 8
+					 9800 0 0 1 &ipic 17 8
+					 9800 0 0 2 &ipic 14 8
+					 9800 0 0 3 &ipic 15 8
+					 9800 0 0 4 &ipic 16 8
 
 					/* IDSEL 0x15 AD21*/
-					 a800 0 0 1 700 14 8
-					 a800 0 0 2 700 15 8
-					 a800 0 0 3 700 16 8
-					 a800 0 0 4 700 17 8
+					 a800 0 0 1 &ipic 14 8
+					 a800 0 0 2 &ipic 15 8
+					 a800 0 0 3 &ipic 16 8
+					 a800 0 0 4 &ipic 17 8
 
 					/* IDSEL 0x16 AD22*/
-					 b000 0 0 1 700 17 8
-					 b000 0 0 2 700 14 8
-					 b000 0 0 3 700 15 8
-					 b000 0 0 4 700 16 8
+					 b000 0 0 1 &ipic 17 8
+					 b000 0 0 2 &ipic 14 8
+					 b000 0 0 3 &ipic 15 8
+					 b000 0 0 4 &ipic 16 8
 
 					/* IDSEL 0x17 AD23*/
-					 b800 0 0 1 700 16 8
-					 b800 0 0 2 700 17 8
-					 b800 0 0 3 700 14 8
-					 b800 0 0 4 700 15 8
+					 b800 0 0 1 &ipic 16 8
+					 b800 0 0 2 &ipic 17 8
+					 b800 0 0 3 &ipic 14 8
+					 b800 0 0 4 &ipic 15 8
 
 					/* IDSEL 0x18 AD24*/
-					 c000 0 0 1 700 15 8
-					 c000 0 0 2 700 16 8
-					 c000 0 0 3 700 17 8
-					 c000 0 0 4 700 14 8>;
-			interrupt-parent = <700>;
+					 c000 0 0 1 &ipic 15 8
+					 c000 0 0 2 &ipic 16 8
+					 c000 0 0 3 &ipic 17 8
+					 c000 0 0 4 &ipic 14 8>;
+			interrupt-parent = < &ipic >;
 			interrupts = <42 8>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 a0000000 a0000000 0 10000000
@@ -180,8 +174,7 @@
 			device_type = "pci";
 		};
 
-		pic@700 {
-			linux,phandle = <700>;
+		ipic: pic@700 {
 			interrupt-controller;
 			#address-cells = <0>;
 			#interrupt-cells = <2>;
@@ -195,8 +188,7 @@
 			device_type = "par_io";
 			num-ports = <7>;
 
-			ucc_pin@01 {
-				linux,phandle = <140001>;
+			pio1: ucc_pin@01 {
 				pio-map = <
 			/* port  pin  dir  open_drain  assignment  has_irq */
 					0  3  1  0  1  0 	/* TxD0 */
@@ -223,8 +215,7 @@
 					2  9  1  0  3  0 	/* GTX_CLK - CLK10 */
 					2  8  2  0  1  0>;	/* GTX125 - CLK9 */
 			};
-			ucc_pin@02 {
-				linux,phandle = <140002>;
+			pio2: ucc_pin@02 {
 				pio-map = <
 			/* port  pin  dir  open_drain  assignment  has_irq */
 					0  11 1  0  1  0   /* TxD0 */
@@ -281,7 +272,7 @@
 			compatible = "fsl_spi";
 			reg = <4c0 40>;
 			interrupts = <2>;
-			interrupt-parent = <80>;
+			interrupt-parent = < &qeic >;
 			mode = "cpu";
 		};
 
@@ -290,7 +281,7 @@
 			compatible = "fsl_spi";
 			reg = <500 40>;
 			interrupts = <1>;
-			interrupt-parent = <80>;
+			interrupt-parent = < &qeic >;
 			mode = "cpu";
 		};
 
@@ -299,7 +290,7 @@
 			compatible = "qe_udc";
 			reg = <6c0 40 8B00 100>;
 			interrupts = <b>;
-			interrupt-parent = <80>;
+			interrupt-parent = < &qeic >;
 			mode = "slave";
 		};
 
@@ -310,12 +301,12 @@
 			device-id = <1>;
 			reg = <2000 200>;
 			interrupts = <20>;
-			interrupt-parent = <80>;
+			interrupt-parent = < &qeic >;
 			mac-address = [ 00 04 9f 00 23 23 ];
 			rx-clock = <0>;
 			tx-clock = <19>;
-			phy-handle = <212000>;
-			pio-handle = <140001>;
+			phy-handle = < &phy0 >;
+			pio-handle = < &pio1 >;
 		};
 
 		ucc@3000 {
@@ -325,12 +316,12 @@
 			device-id = <2>;
 			reg = <3000 200>;
 			interrupts = <21>;
-			interrupt-parent = <80>;
+			interrupt-parent = < &qeic >;
 			mac-address = [ 00 11 22 33 44 55 ];
 			rx-clock = <0>;
 			tx-clock = <14>;
-			phy-handle = <212001>;
-			pio-handle = <140002>;
+			phy-handle = < &phy1 >;
+			pio-handle = < &pio2 >;
 		};
 
 		mdio@2120 {
@@ -340,26 +331,23 @@
 			device_type = "mdio";
 			compatible = "ucc_geth_phy";
 
-			ethernet-phy@00 {
-				linux,phandle = <212000>;
-				interrupt-parent = <700>;
-				interrupts = <11 2>;
+			phy0: ethernet-phy@00 {
+				interrupt-parent = < &ipic >;
+				interrupts = <11 8>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 				interface = <6>; //ENET_1000_GMII
 			};
-			ethernet-phy@01 {
-				linux,phandle = <212001>;
-				interrupt-parent = <700>;
-				interrupts = <12 2>;
+			phy1: ethernet-phy@01 {
+				interrupt-parent = < &ipic >;
+				interrupts = <12 8>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 				interface = <6>;
 			};
 		};
 
-		qeic@80 {
-			linux,phandle = <80>;
+		qeic: qeic@80 {
 			interrupt-controller;
 			device_type = "qeic";
 			#address-cells = <0>;
@@ -368,7 +356,7 @@
 			built-in;
 			big-endian;
 			interrupts = <20 8 21 8>; //high:32 low:33
-			interrupt-parent = <700>;
+			interrupt-parent = < &ipic >;
 		};
 
 	};
diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts
index 5f41c1f..3c0917f 100644
--- a/arch/powerpc/boot/dts/mpc8540ads.dts
+++ b/arch/powerpc/boot/dts/mpc8540ads.dts
@@ -12,16 +12,14 @@
 
 / {
 	model = "MPC8540ADS";
-	compatible = "MPC85xxADS";
+	compatible = "MPC8540ADS", "MPC85xxADS";
 	#address-cells = <1>;
 	#size-cells = <1>;
-	linux,phandle = <100>;
 
 	cpus {
 		#cpus = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		linux,phandle = <200>;
 
 		PowerPC,8540@0 {
 			device_type = "cpu";
@@ -34,13 +32,11 @@
 			bus-frequency = <0>;	// 166 MHz
 			clock-frequency = <0>;	// 825 MHz, from uboot
 			32-bit;
-			linux,phandle = <201>;
 		};
 	};
 
 	memory {
 		device_type = "memory";
-		linux,phandle = <300>;
 		reg = <00000000 08000000>;	// 128M at 0x0
 	};
 
@@ -58,7 +54,7 @@
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			interrupts = <1b 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 			dfsrr;
 		};
 
@@ -68,24 +64,20 @@
 			device_type = "mdio";
 			compatible = "gianfar";
 			reg = <24520 20>;
-			linux,phandle = <24520>;
-			ethernet-phy@0 {
-				linux,phandle = <2452000>;
-				interrupt-parent = <40000>;
+			phy0: ethernet-phy@0 {
+				interrupt-parent = <&mpic>;
 				interrupts = <35 1>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@1 {
-				linux,phandle = <2452001>;
-				interrupt-parent = <40000>;
+			phy1: ethernet-phy@1 {
+				interrupt-parent = <&mpic>;
 				interrupts = <35 1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@3 {
-				linux,phandle = <2452003>;
-				interrupt-parent = <40000>;
+			phy3: ethernet-phy@3 {
+				interrupt-parent = <&mpic>;
 				interrupts = <37 1>;
 				reg = <3>;
 				device_type = "ethernet-phy";
@@ -102,8 +94,8 @@
 			address = [ 00 E0 0C 00 73 00 ];
 			local-mac-address = [ 00 E0 0C 00 73 00 ];
 			interrupts = <d 2 e 2 12 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452000>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy0>;
 		};
 
 		ethernet@25000 {
@@ -116,8 +108,8 @@
 			address = [ 00 E0 0C 00 73 01 ];
 			local-mac-address = [ 00 E0 0C 00 73 01 ];
 			interrupts = <13 2 14 2 18 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452001>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy1>;
 		};
 
 		ethernet@26000 {
@@ -130,8 +122,8 @@
 			address = [ 00 E0 0C 00 73 02 ];
 			local-mac-address = [ 00 E0 0C 00 73 02 ];
 			interrupts = <19 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452003>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy3>;
 		};
 
 		serial@4500 {
@@ -140,7 +132,7 @@
 			reg = <4500 100>; 	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			interrupts = <1a 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 		};
 
 		serial@4600 {
@@ -149,85 +141,84 @@
 			reg = <4600 100>;	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			interrupts = <1a 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 		};
 		pci@8000 {
-			linux,phandle = <8000>;
 			interrupt-map-mask = <f800 0 0 7>;
 			interrupt-map = <
 
 				/* IDSEL 0x02 */
-				1000 0 0 1 40000 31 1
-				1000 0 0 2 40000 32 1
-				1000 0 0 3 40000 33 1
-				1000 0 0 4 40000 34 1
+				1000 0 0 1 &mpic 31 1
+				1000 0 0 2 &mpic 32 1
+				1000 0 0 3 &mpic 33 1
+				1000 0 0 4 &mpic 34 1
 
 				/* IDSEL 0x03 */
-				1800 0 0 1 40000 34 1
-				1800 0 0 2 40000 31 1
-				1800 0 0 3 40000 32 1
-				1800 0 0 4 40000 33 1
+				1800 0 0 1 &mpic 34 1
+				1800 0 0 2 &mpic 31 1
+				1800 0 0 3 &mpic 32 1
+				1800 0 0 4 &mpic 33 1
 
 				/* IDSEL 0x04 */
-				2000 0 0 1 40000 33 1
-				2000 0 0 2 40000 34 1
-				2000 0 0 3 40000 31 1
-				2000 0 0 4 40000 32 1
+				2000 0 0 1 &mpic 33 1
+				2000 0 0 2 &mpic 34 1
+				2000 0 0 3 &mpic 31 1
+				2000 0 0 4 &mpic 32 1
 
 				/* IDSEL 0x05 */
-				2800 0 0 1 40000 32 1
-				2800 0 0 2 40000 33 1
-				2800 0 0 3 40000 34 1
-				2800 0 0 4 40000 31 1
+				2800 0 0 1 &mpic 32 1
+				2800 0 0 2 &mpic 33 1
+				2800 0 0 3 &mpic 34 1
+				2800 0 0 4 &mpic 31 1
 
 				/* IDSEL 0x0c */
-				6000 0 0 1 40000 31 1
-				6000 0 0 2 40000 32 1
-				6000 0 0 3 40000 33 1
-				6000 0 0 4 40000 34 1
+				6000 0 0 1 &mpic 31 1
+				6000 0 0 2 &mpic 32 1
+				6000 0 0 3 &mpic 33 1
+				6000 0 0 4 &mpic 34 1
 
 				/* IDSEL 0x0d */
-				6800 0 0 1 40000 34 1
-				6800 0 0 2 40000 31 1
-				6800 0 0 3 40000 32 1
-				6800 0 0 4 40000 33 1
+				6800 0 0 1 &mpic 34 1
+				6800 0 0 2 &mpic 31 1
+				6800 0 0 3 &mpic 32 1
+				6800 0 0 4 &mpic 33 1
 
 				/* IDSEL 0x0e */
-				7000 0 0 1 40000 33 1
-				7000 0 0 2 40000 34 1
-				7000 0 0 3 40000 31 1
-				7000 0 0 4 40000 32 1
+				7000 0 0 1 &mpic 33 1
+				7000 0 0 2 &mpic 34 1
+				7000 0 0 3 &mpic 31 1
+				7000 0 0 4 &mpic 32 1
 
 				/* IDSEL 0x0f */
-				7800 0 0 1 40000 32 1
-				7800 0 0 2 40000 33 1
-				7800 0 0 3 40000 34 1
-				7800 0 0 4 40000 31 1
+				7800 0 0 1 &mpic 32 1
+				7800 0 0 2 &mpic 33 1
+				7800 0 0 3 &mpic 34 1
+				7800 0 0 4 &mpic 31 1
 
 				/* IDSEL 0x12 */
-				9000 0 0 1 40000 31 1
-				9000 0 0 2 40000 32 1
-				9000 0 0 3 40000 33 1
-				9000 0 0 4 40000 34 1
+				9000 0 0 1 &mpic 31 1
+				9000 0 0 2 &mpic 32 1
+				9000 0 0 3 &mpic 33 1
+				9000 0 0 4 &mpic 34 1
 
 				/* IDSEL 0x13 */
-				9800 0 0 1 40000 34 1
-				9800 0 0 2 40000 31 1
-				9800 0 0 3 40000 32 1
-				9800 0 0 4 40000 33 1
+				9800 0 0 1 &mpic 34 1
+				9800 0 0 2 &mpic 31 1
+				9800 0 0 3 &mpic 32 1
+				9800 0 0 4 &mpic 33 1
 
 				/* IDSEL 0x14 */
-				a000 0 0 1 40000 33 1
-				a000 0 0 2 40000 34 1
-				a000 0 0 3 40000 31 1
-				a000 0 0 4 40000 32 1
+				a000 0 0 1 &mpic 33 1
+				a000 0 0 2 &mpic 34 1
+				a000 0 0 3 &mpic 31 1
+				a000 0 0 4 &mpic 32 1
 
 				/* IDSEL 0x15 */
-				a800 0 0 1 40000 32 1
-				a800 0 0 2 40000 33 1
-				a800 0 0 3 40000 34 1
-				a800 0 0 4 40000 31 1>;
-			interrupt-parent = <40000>;
+				a800 0 0 1 &mpic 32 1
+				a800 0 0 2 &mpic 33 1
+				a800 0 0 3 &mpic 34 1
+				a800 0 0 4 &mpic 31 1>;
+			interrupt-parent = <&mpic>;
 			interrupts = <08 2>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 80000000 80000000 0 20000000
@@ -241,8 +232,7 @@
 			device_type = "pci";
 		};
 
-		pic@40000 {
-			linux,phandle = <40000>;
+		mpic: pic@40000 {
 			clock-frequency = <0>;
 			interrupt-controller;
 			#address-cells = <0>;
diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts
index 7be0bc6..2a1ae76 100644
--- a/arch/powerpc/boot/dts/mpc8541cds.dts
+++ b/arch/powerpc/boot/dts/mpc8541cds.dts
@@ -12,16 +12,14 @@
 
 / {
 	model = "MPC8541CDS";
-	compatible = "MPC85xxCDS";
+	compatible = "MPC8541CDS", "MPC85xxCDS";
 	#address-cells = <1>;
 	#size-cells = <1>;
-	linux,phandle = <100>;
 
 	cpus {
 		#cpus = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		linux,phandle = <200>;
 
 		PowerPC,8541@0 {
 			device_type = "cpu";
@@ -34,13 +32,11 @@
 			bus-frequency = <0>;	// 166 MHz
 			clock-frequency = <0>;	// 825 MHz, from uboot
 			32-bit;
-			linux,phandle = <201>;
 		};
 	};
 
 	memory {
 		device_type = "memory";
-		linux,phandle = <300>;
 		reg = <00000000 08000000>;	// 128M at 0x0
 	};
 
@@ -58,7 +54,7 @@
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			interrupts = <1b 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 			dfsrr;
 		};
 
@@ -68,17 +64,14 @@
 			device_type = "mdio";
 			compatible = "gianfar";
 			reg = <24520 20>;
-			linux,phandle = <24520>;
-			ethernet-phy@0 {
-				linux,phandle = <2452000>;
-				interrupt-parent = <40000>;
+			phy0: ethernet-phy@0 {
+				interrupt-parent = <&mpic>;
 				interrupts = <35 0>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@1 {
-				linux,phandle = <2452001>;
-				interrupt-parent = <40000>;
+			phy1: ethernet-phy@1 {
+				interrupt-parent = <&mpic>;
 				interrupts = <35 0>;
 				reg = <1>;
 				device_type = "ethernet-phy";
@@ -94,8 +87,8 @@
 			reg = <24000 1000>;
 			local-mac-address = [ 00 E0 0C 00 73 00 ];
 			interrupts = <d 2 e 2 12 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452000>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy0>;
 		};
 
 		ethernet@25000 {
@@ -107,8 +100,8 @@
 			reg = <25000 1000>;
 			local-mac-address = [ 00 E0 0C 00 73 01 ];
 			interrupts = <13 2 14 2 18 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452001>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy1>;
 		};
 
 		serial@4500 {
@@ -117,7 +110,7 @@
 			reg = <4500 100>; 	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			interrupts = <1a 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 		};
 
 		serial@4600 {
@@ -126,57 +119,56 @@
 			reg = <4600 100>;	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			interrupts = <1a 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 		};
 
-		pci@8000 {
-			linux,phandle = <8000>;
+		pci1: pci@8000 {
 			interrupt-map-mask = <1f800 0 0 7>;
 			interrupt-map = <
 
 				/* IDSEL 0x10 */
-				08000 0 0 1 40000 30 1
-				08000 0 0 2 40000 31 1
-				08000 0 0 3 40000 32 1
-				08000 0 0 4 40000 33 1
+				08000 0 0 1 &mpic 30 1
+				08000 0 0 2 &mpic 31 1
+				08000 0 0 3 &mpic 32 1
+				08000 0 0 4 &mpic 33 1
 
 				/* IDSEL 0x11 */
-				08800 0 0 1 40000 30 1
-				08800 0 0 2 40000 31 1
-				08800 0 0 3 40000 32 1
-				08800 0 0 4 40000 33 1
+				08800 0 0 1 &mpic 30 1
+				08800 0 0 2 &mpic 31 1
+				08800 0 0 3 &mpic 32 1
+				08800 0 0 4 &mpic 33 1
 
 				/* IDSEL 0x12 (Slot 1) */
-				09000 0 0 1 40000 30 1
-				09000 0 0 2 40000 31 1
-				09000 0 0 3 40000 32 1
-				09000 0 0 4 40000 33 1
+				09000 0 0 1 &mpic 30 1
+				09000 0 0 2 &mpic 31 1
+				09000 0 0 3 &mpic 32 1
+				09000 0 0 4 &mpic 33 1
 
 				/* IDSEL 0x13 (Slot 2) */
-				09800 0 0 1 40000 31 1
-				09800 0 0 2 40000 32 1
-				09800 0 0 3 40000 33 1
-				09800 0 0 4 40000 30 1
+				09800 0 0 1 &mpic 31 1
+				09800 0 0 2 &mpic 32 1
+				09800 0 0 3 &mpic 33 1
+				09800 0 0 4 &mpic 30 1
 
 				/* IDSEL 0x14 (Slot 3) */
-				0a000 0 0 1 40000 32 1
-				0a000 0 0 2 40000 33 1
-				0a000 0 0 3 40000 30 1
-				0a000 0 0 4 40000 31 1
+				0a000 0 0 1 &mpic 32 1
+				0a000 0 0 2 &mpic 33 1
+				0a000 0 0 3 &mpic 30 1
+				0a000 0 0 4 &mpic 31 1
 
 				/* IDSEL 0x15 (Slot 4) */
-				0a800 0 0 1 40000 33 1
-				0a800 0 0 2 40000 30 1
-				0a800 0 0 3 40000 31 1
-				0a800 0 0 4 40000 32 1
+				0a800 0 0 1 &mpic 33 1
+				0a800 0 0 2 &mpic 30 1
+				0a800 0 0 3 &mpic 31 1
+				0a800 0 0 4 &mpic 32 1
 
 				/* Bus 1 (Tundra Bridge) */
 				/* IDSEL 0x12 (ISA bridge) */
-				19000 0 0 1 40000 30 1
-				19000 0 0 2 40000 31 1
-				19000 0 0 3 40000 32 1
-				19000 0 0 4 40000 33 1>;
-			interrupt-parent = <40000>;
+				19000 0 0 1 &mpic 30 1
+				19000 0 0 2 &mpic 31 1
+				19000 0 0 3 &mpic 32 1
+				19000 0 0 4 &mpic 33 1>;
+			interrupt-parent = <&mpic>;
 			interrupts = <08 2>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 80000000 80000000 0 20000000
@@ -200,21 +192,20 @@
 				compatible = "chrp,iic";
 				big-endian;
 				interrupts = <1>;
-				interrupt-parent = <8000>;
+				interrupt-parent = <&pci1>;
 			};
 		};
 
 		pci@9000 {
-			linux,phandle = <9000>;
 			interrupt-map-mask = <f800 0 0 7>;
 			interrupt-map = <
 
 				/* IDSEL 0x15 */
-				a800 0 0 1 40000 3b 1
-				a800 0 0 2 40000 3b 1
-				a800 0 0 3 40000 3b 1
-				a800 0 0 4 40000 3b 1>;
-			interrupt-parent = <40000>;
+				a800 0 0 1 &mpic 3b 1
+				a800 0 0 2 &mpic 3b 1
+				a800 0 0 3 &mpic 3b 1
+				a800 0 0 4 &mpic 3b 1>;
+			interrupt-parent = <&mpic>;
 			interrupts = <09 2>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 a0000000 a0000000 0 20000000
@@ -228,8 +219,7 @@
 			device_type = "pci";
 		};
 
-		pic@40000 {
-			linux,phandle = <40000>;
+		mpic: pic@40000 {
 			clock-frequency = <0>;
 			interrupt-controller;
 			#address-cells = <0>;
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts
index 893d795..7eb5d81 100644
--- a/arch/powerpc/boot/dts/mpc8548cds.dts
+++ b/arch/powerpc/boot/dts/mpc8548cds.dts
@@ -12,16 +12,14 @@
 
 / {
 	model = "MPC8548CDS";
-	compatible = "MPC85xxCDS";
+	compatible = "MPC8548CDS", "MPC85xxCDS";
 	#address-cells = <1>;
 	#size-cells = <1>;
-	linux,phandle = <100>;
 
 	cpus {
 		#cpus = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		linux,phandle = <200>;
 
 		PowerPC,8548@0 {
 			device_type = "cpu";
@@ -34,13 +32,11 @@
 			bus-frequency = <0>;	// 166 MHz
 			clock-frequency = <0>;	// 825 MHz, from uboot
 			32-bit;
-			linux,phandle = <201>;
 		};
 	};
 
 	memory {
 		device_type = "memory";
-		linux,phandle = <300>;
 		reg = <00000000 08000000>;	// 128M at 0x0
 	};
 
@@ -58,7 +54,7 @@
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			interrupts = <1b 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 			dfsrr;
 		};
 
@@ -68,32 +64,26 @@
 			device_type = "mdio";
 			compatible = "gianfar";
 			reg = <24520 20>;
-			linux,phandle = <24520>;
-			ethernet-phy@0 {
-				linux,phandle = <2452000>;
-				interrupt-parent = <40000>;
+			phy0: ethernet-phy@0 {
+				interrupt-parent = <&mpic>;
 				interrupts = <35 0>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@1 {
-				linux,phandle = <2452001>;
-				interrupt-parent = <40000>;
+			phy1: ethernet-phy@1 {
+				interrupt-parent = <&mpic>;
 				interrupts = <35 0>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 			};
-
-			ethernet-phy@2 {
-				linux,phandle = <2452002>;
-				interrupt-parent = <40000>;
+			phy2: ethernet-phy@2 {
+				interrupt-parent = <&mpic>;
 				interrupts = <35 0>;
 				reg = <2>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@3 {
-				linux,phandle = <2452003>;
-				interrupt-parent = <40000>;
+			phy3: ethernet-phy@3 {
+				interrupt-parent = <&mpic>;
 				interrupts = <35 0>;
 				reg = <3>;
 				device_type = "ethernet-phy";
@@ -109,8 +99,8 @@
 			reg = <24000 1000>;
 			local-mac-address = [ 00 E0 0C 00 73 00 ];
 			interrupts = <d 2 e 2 12 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452000>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy0>;
 		};
 
 		ethernet@25000 {
@@ -122,10 +112,11 @@
 			reg = <25000 1000>;
 			local-mac-address = [ 00 E0 0C 00 73 01 ];
 			interrupts = <13 2 14 2 18 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452001>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy1>;
 		};
 
+/* eTSEC 3/4 are currently broken
 		ethernet@26000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -135,11 +126,10 @@
 			reg = <26000 1000>;
 			local-mac-address = [ 00 E0 0C 00 73 02 ];
 			interrupts = <f 2 10 2 11 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452001>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy2>;
 		};
 
-/* eTSEC 4 is currently broken
 		ethernet@27000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -149,8 +139,8 @@
 			reg = <27000 1000>;
 			local-mac-address = [ 00 E0 0C 00 73 03 ];
 			interrupts = <15 2 16 2 17 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452001>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy3>;
 		};
  */
 
@@ -160,7 +150,7 @@
 			reg = <4500 100>; 	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			interrupts = <1a 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 		};
 
 		serial@4600 {
@@ -169,57 +159,56 @@
 			reg = <4600 100>;	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			interrupts = <1a 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 		};
 
-		pci@8000 {
-			linux,phandle = <8000>;
+		pci1: pci@8000 {
 			interrupt-map-mask = <1f800 0 0 7>;
 			interrupt-map = <
 
 				/* IDSEL 0x10 */
-				08000 0 0 1 40000 30 1
-				08000 0 0 2 40000 31 1
-				08000 0 0 3 40000 32 1
-				08000 0 0 4 40000 33 1
+				08000 0 0 1 &mpic 30 1
+				08000 0 0 2 &mpic 31 1
+				08000 0 0 3 &mpic 32 1
+				08000 0 0 4 &mpic 33 1
 
 				/* IDSEL 0x11 */
-				08800 0 0 1 40000 30 1
-				08800 0 0 2 40000 31 1
-				08800 0 0 3 40000 32 1
-				08800 0 0 4 40000 33 1
+				08800 0 0 1 &mpic 30 1
+				08800 0 0 2 &mpic 31 1
+				08800 0 0 3 &mpic 32 1
+				08800 0 0 4 &mpic 33 1
 
 				/* IDSEL 0x12 (Slot 1) */
-				09000 0 0 1 40000 30 1
-				09000 0 0 2 40000 31 1
-				09000 0 0 3 40000 32 1
-				09000 0 0 4 40000 33 1
+				09000 0 0 1 &mpic 30 1
+				09000 0 0 2 &mpic 31 1
+				09000 0 0 3 &mpic 32 1
+				09000 0 0 4 &mpic 33 1
 
 				/* IDSEL 0x13 (Slot 2) */
-				09800 0 0 1 40000 31 1
-				09800 0 0 2 40000 32 1
-				09800 0 0 3 40000 33 1
-				09800 0 0 4 40000 30 1
+				09800 0 0 1 &mpic 31 1
+				09800 0 0 2 &mpic 32 1
+				09800 0 0 3 &mpic 33 1
+				09800 0 0 4 &mpic 30 1
 
 				/* IDSEL 0x14 (Slot 3) */
-				0a000 0 0 1 40000 32 1
-				0a000 0 0 2 40000 33 1
-				0a000 0 0 3 40000 30 1
-				0a000 0 0 4 40000 31 1
+				0a000 0 0 1 &mpic 32 1
+				0a000 0 0 2 &mpic 33 1
+				0a000 0 0 3 &mpic 30 1
+				0a000 0 0 4 &mpic 31 1
 
 				/* IDSEL 0x15 (Slot 4) */
-				0a800 0 0 1 40000 33 1
-				0a800 0 0 2 40000 30 1
-				0a800 0 0 3 40000 31 1
-				0a800 0 0 4 40000 32 1
+				0a800 0 0 1 &mpic 33 1
+				0a800 0 0 2 &mpic 30 1
+				0a800 0 0 3 &mpic 31 1
+				0a800 0 0 4 &mpic 32 1
 
 				/* Bus 1 (Tundra Bridge) */
 				/* IDSEL 0x12 (ISA bridge) */
-				19000 0 0 1 40000 30 1
-				19000 0 0 2 40000 31 1
-				19000 0 0 3 40000 32 1
-				19000 0 0 4 40000 33 1>;
-			interrupt-parent = <40000>;
+				19000 0 0 1 &mpic 30 1
+				19000 0 0 2 &mpic 31 1
+				19000 0 0 3 &mpic 32 1
+				19000 0 0 4 &mpic 33 1>;
+			interrupt-parent = <&mpic>;
 			interrupts = <08 2>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 80000000 80000000 0 20000000
@@ -243,21 +232,20 @@
 				compatible = "chrp,iic";
 				big-endian;
 				interrupts = <1>;
-				interrupt-parent = <8000>;
+				interrupt-parent = <&pci1>;
 			};
 		};
 
 		pci@9000 {
-			linux,phandle = <9000>;
 			interrupt-map-mask = <f800 0 0 7>;
 			interrupt-map = <
 
 				/* IDSEL 0x15 */
-				a800 0 0 1 40000 3b 1
-				a800 0 0 2 40000 3b 1
-				a800 0 0 3 40000 3b 1
-				a800 0 0 4 40000 3b 1>;
-			interrupt-parent = <40000>;
+				a800 0 0 1 &mpic 3b 1
+				a800 0 0 2 &mpic 3b 1
+				a800 0 0 3 &mpic 3b 1
+				a800 0 0 4 &mpic 3b 1>;
+			interrupt-parent = <&mpic>;
 			interrupts = <09 2>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 a0000000 a0000000 0 20000000
@@ -271,8 +259,7 @@
 			device_type = "pci";
 		};
 
-		pic@40000 {
-			linux,phandle = <40000>;
+		mpic: pic@40000 {
 			clock-frequency = <0>;
 			interrupt-controller;
 			#address-cells = <0>;
diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts
index 118f5a8..5f9c102 100644
--- a/arch/powerpc/boot/dts/mpc8555cds.dts
+++ b/arch/powerpc/boot/dts/mpc8555cds.dts
@@ -12,16 +12,14 @@
 
 / {
 	model = "MPC8555CDS";
-	compatible = "MPC85xxCDS";
+	compatible = "MPC8555CDS", "MPC85xxCDS";
 	#address-cells = <1>;
 	#size-cells = <1>;
-	linux,phandle = <100>;
 
 	cpus {
 		#cpus = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		linux,phandle = <200>;
 
 		PowerPC,8555@0 {
 			device_type = "cpu";
@@ -34,13 +32,11 @@
 			bus-frequency = <0>;	// 166 MHz
 			clock-frequency = <0>;	// 825 MHz, from uboot
 			32-bit;
-			linux,phandle = <201>;
 		};
 	};
 
 	memory {
 		device_type = "memory";
-		linux,phandle = <300>;
 		reg = <00000000 08000000>;	// 128M at 0x0
 	};
 
@@ -58,7 +54,7 @@
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			interrupts = <1b 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 			dfsrr;
 		};
 
@@ -68,17 +64,14 @@
 			device_type = "mdio";
 			compatible = "gianfar";
 			reg = <24520 20>;
-			linux,phandle = <24520>;
-			ethernet-phy@0 {
-				linux,phandle = <2452000>;
-				interrupt-parent = <40000>;
+			phy0: ethernet-phy@0 {
+				interrupt-parent = <&mpic>;
 				interrupts = <35 0>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@1 {
-				linux,phandle = <2452001>;
-				interrupt-parent = <40000>;
+			phy1: ethernet-phy@1 {
+				interrupt-parent = <&mpic>;
 				interrupts = <35 0>;
 				reg = <1>;
 				device_type = "ethernet-phy";
@@ -94,8 +87,8 @@
 			reg = <24000 1000>;
 			local-mac-address = [ 00 E0 0C 00 73 00 ];
 			interrupts = <0d 2 0e 2 12 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452000>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy0>;
 		};
 
 		ethernet@25000 {
@@ -107,8 +100,8 @@
 			reg = <25000 1000>;
 			local-mac-address = [ 00 E0 0C 00 73 01 ];
 			interrupts = <13 2 14 2 18 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452001>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy1>;
 		};
 
 		serial@4500 {
@@ -117,7 +110,7 @@
 			reg = <4500 100>; 	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			interrupts = <1a 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 		};
 
 		serial@4600 {
@@ -126,57 +119,56 @@
 			reg = <4600 100>;	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			interrupts = <1a 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 		};
 
-		pci@8000 {
-			linux,phandle = <8000>;
+		pci1: pci@8000 {
 			interrupt-map-mask = <1f800 0 0 7>;
 			interrupt-map = <
 
 				/* IDSEL 0x10 */
-				08000 0 0 1 40000 30 1
-				08000 0 0 2 40000 31 1
-				08000 0 0 3 40000 32 1
-				08000 0 0 4 40000 33 1
+				08000 0 0 1 &mpic 30 1
+				08000 0 0 2 &mpic 31 1
+				08000 0 0 3 &mpic 32 1
+				08000 0 0 4 &mpic 33 1
 
 				/* IDSEL 0x11 */
-				08800 0 0 1 40000 30 1
-				08800 0 0 2 40000 31 1
-				08800 0 0 3 40000 32 1
-				08800 0 0 4 40000 33 1
+				08800 0 0 1 &mpic 30 1
+				08800 0 0 2 &mpic 31 1
+				08800 0 0 3 &mpic 32 1
+				08800 0 0 4 &mpic 33 1
 
 				/* IDSEL 0x12 (Slot 1) */
-				09000 0 0 1 40000 30 1
-				09000 0 0 2 40000 31 1
-				09000 0 0 3 40000 32 1
-				09000 0 0 4 40000 33 1
+				09000 0 0 1 &mpic 30 1
+				09000 0 0 2 &mpic 31 1
+				09000 0 0 3 &mpic 32 1
+				09000 0 0 4 &mpic 33 1
 
 				/* IDSEL 0x13 (Slot 2) */
-				09800 0 0 1 40000 31 1
-				09800 0 0 2 40000 32 1
-				09800 0 0 3 40000 33 1
-				09800 0 0 4 40000 30 1
+				09800 0 0 1 &mpic 31 1
+				09800 0 0 2 &mpic 32 1
+				09800 0 0 3 &mpic 33 1
+				09800 0 0 4 &mpic 30 1
 
 				/* IDSEL 0x14 (Slot 3) */
-				0a000 0 0 1 40000 32 1
-				0a000 0 0 2 40000 33 1
-				0a000 0 0 3 40000 30 1
-				0a000 0 0 4 40000 31 1
+				0a000 0 0 1 &mpic 32 1
+				0a000 0 0 2 &mpic 33 1
+				0a000 0 0 3 &mpic 30 1
+				0a000 0 0 4 &mpic 31 1
 
 				/* IDSEL 0x15 (Slot 4) */
-				0a800 0 0 1 40000 33 1
-				0a800 0 0 2 40000 30 1
-				0a800 0 0 3 40000 31 1
-				0a800 0 0 4 40000 32 1
+				0a800 0 0 1 &mpic 33 1
+				0a800 0 0 2 &mpic 30 1
+				0a800 0 0 3 &mpic 31 1
+				0a800 0 0 4 &mpic 32 1
 
 				/* Bus 1 (Tundra Bridge) */
 				/* IDSEL 0x12 (ISA bridge) */
-				19000 0 0 1 40000 30 1
-				19000 0 0 2 40000 31 1
-				19000 0 0 3 40000 32 1
-				19000 0 0 4 40000 33 1>;
-			interrupt-parent = <40000>;
+				19000 0 0 1 &mpic 30 1
+				19000 0 0 2 &mpic 31 1
+				19000 0 0 3 &mpic 32 1
+				19000 0 0 4 &mpic 33 1>;
+			interrupt-parent = <&mpic>;
 			interrupts = <08 2>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 80000000 80000000 0 20000000
@@ -200,21 +192,20 @@
 				compatible = "chrp,iic";
 				big-endian;
 				interrupts = <1>;
-				interrupt-parent = <8000>;
+				interrupt-parent = <&pci1>;
 			};
 		};
 
 		pci@9000 {
-			linux,phandle = <9000>;
 			interrupt-map-mask = <f800 0 0 7>;
 			interrupt-map = <
 
 				/* IDSEL 0x15 */
-				a800 0 0 1 40000 3b 1
-				a800 0 0 2 40000 3b 1
-				a800 0 0 3 40000 3b 1
-				a800 0 0 4 40000 3b 1>;
-			interrupt-parent = <40000>;
+				a800 0 0 1 &mpic 3b 1
+				a800 0 0 2 &mpic 3b 1
+				a800 0 0 3 &mpic 3b 1
+				a800 0 0 4 &mpic 3b 1>;
+			interrupt-parent = <&mpic>;
 			interrupts = <09 2>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 a0000000 a0000000 0 20000000
@@ -228,8 +219,7 @@
 			device_type = "pci";
 		};
 
-		pic@40000 {
-			linux,phandle = <40000>;
+		mpic: pic@40000 {
 			clock-frequency = <0>;
 			interrupt-controller;
 			#address-cells = <0>;
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts
index 119bd5d..1050263 100644
--- a/arch/powerpc/boot/dts/mpc8560ads.dts
+++ b/arch/powerpc/boot/dts/mpc8560ads.dts
@@ -12,16 +12,14 @@
 
 / {
 	model = "MPC8560ADS";
-	compatible = "MPC85xxADS";
+	compatible = "MPC8560ADS", "MPC85xxADS";
 	#address-cells = <1>;
 	#size-cells = <1>;
-	linux,phandle = <100>;
 
 	cpus {
 		#cpus = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		linux,phandle = <200>;
 
 		PowerPC,8560@0 {
 			device_type = "cpu";
@@ -34,14 +32,11 @@
 			bus-frequency = <13ab6680>;
 			clock-frequency = <312c8040>;
 			32-bit;
-			linux,phandle = <201>;
-			linux,boot-cpu;
 		};
 	};
 
 	memory {
 		device_type = "memory";
-		linux,phandle = <300>;
 		reg = <00000000 10000000>;
 	};
 
@@ -58,33 +53,28 @@
 			device_type = "mdio";
 			compatible = "gianfar";
 			reg = <24520 20>;
-			linux,phandle = <24520>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			ethernet-phy@0 {
-				linux,phandle = <2452000>;
-				interrupt-parent = <40000>;
+			phy0: ethernet-phy@0 {
+				interrupt-parent = <&mpic>;
 				interrupts = <35 1>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@1 {
-				linux,phandle = <2452001>;
-				interrupt-parent = <40000>;
+			phy1: ethernet-phy@1 {
+				interrupt-parent = <&mpic>;
 				interrupts = <35 1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@2 {
-				linux,phandle = <2452002>;
-				interrupt-parent = <40000>;
+			phy2: ethernet-phy@2 {
+				interrupt-parent = <&mpic>;
 				interrupts = <37 1>;
 				reg = <2>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@3 {
-				linux,phandle = <2452003>;
-				interrupt-parent = <40000>;
+			phy3: ethernet-phy@3 {
+				interrupt-parent = <&mpic>;
 				interrupts = <37 1>;
 				reg = <3>;
 				device_type = "ethernet-phy";
@@ -98,8 +88,8 @@
 			reg = <24000 1000>;
 			address = [ 00 00 0C 00 00 FD ];
 			interrupts = <d 2 e 2 12 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452000>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy0>;
 		};
 
 		ethernet@25000 {
@@ -111,12 +101,11 @@
 			reg = <25000 1000>;
 			address = [ 00 00 0C 00 01 FD ];
 			interrupts = <13 2 14 2 18 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452001>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy1>;
 		};
 
 		pci@8000 {
-			linux,phandle = <8000>;
 			#interrupt-cells = <1>;
 			#size-cells = <2>;
 			#address-cells = <3>;
@@ -128,96 +117,94 @@
 			interrupt-map = <
 
 					/* IDSEL 0x2 */
-					 1000 0 0 1 40000 31 1
-					 1000 0 0 2 40000 32 1
-					 1000 0 0 3 40000 33 1
-					 1000 0 0 4 40000 34 1
+					 1000 0 0 1 &mpic 31 1
+					 1000 0 0 2 &mpic 32 1
+					 1000 0 0 3 &mpic 33 1
+					 1000 0 0 4 &mpic 34 1
 
 					/* IDSEL 0x3 */
-					 1800 0 0 1 40000 34 1
-					 1800 0 0 2 40000 31 1
-					 1800 0 0 3 40000 32 1
-					 1800 0 0 4 40000 33 1
+					 1800 0 0 1 &mpic 34 1
+					 1800 0 0 2 &mpic 31 1
+					 1800 0 0 3 &mpic 32 1
+					 1800 0 0 4 &mpic 33 1
 
 					/* IDSEL 0x4 */
-					 2000 0 0 1 40000 33 1
-					 2000 0 0 2 40000 34 1
-					 2000 0 0 3 40000 31 1
-					 2000 0 0 4 40000 32 1
+					 2000 0 0 1 &mpic 33 1
+					 2000 0 0 2 &mpic 34 1
+					 2000 0 0 3 &mpic 31 1
+					 2000 0 0 4 &mpic 32 1
 
 					/* IDSEL 0x5  */
-					 2800 0 0 1 40000 32 1
-					 2800 0 0 2 40000 33 1
-					 2800 0 0 3 40000 34 1
-					 2800 0 0 4 40000 31 1
+					 2800 0 0 1 &mpic 32 1
+					 2800 0 0 2 &mpic 33 1
+					 2800 0 0 3 &mpic 34 1
+					 2800 0 0 4 &mpic 31 1
 
 					/* IDSEL 12 */
-					 6000 0 0 1 40000 31 1
-					 6000 0 0 2 40000 32 1
-					 6000 0 0 3 40000 33 1
-					 6000 0 0 4 40000 34 1
+					 6000 0 0 1 &mpic 31 1
+					 6000 0 0 2 &mpic 32 1
+					 6000 0 0 3 &mpic 33 1
+					 6000 0 0 4 &mpic 34 1
 
 					/* IDSEL 13 */
-					 6800 0 0 1 40000 34 1
-					 6800 0 0 2 40000 31 1
-					 6800 0 0 3 40000 32 1
-					 6800 0 0 4 40000 33 1
+					 6800 0 0 1 &mpic 34 1
+					 6800 0 0 2 &mpic 31 1
+					 6800 0 0 3 &mpic 32 1
+					 6800 0 0 4 &mpic 33 1
 
 					/* IDSEL 14*/
-					 7000 0 0 1 40000 33 1
-					 7000 0 0 2 40000 34 1
-					 7000 0 0 3 40000 31 1
-					 7000 0 0 4 40000 32 1
+					 7000 0 0 1 &mpic 33 1
+					 7000 0 0 2 &mpic 34 1
+					 7000 0 0 3 &mpic 31 1
+					 7000 0 0 4 &mpic 32 1
 
 					/* IDSEL 15 */
-					 7800 0 0 1 40000 32 1
-					 7800 0 0 2 40000 33 1
-					 7800 0 0 3 40000 34 1
-					 7800 0 0 4 40000 31 1
+					 7800 0 0 1 &mpic 32 1
+					 7800 0 0 2 &mpic 33 1
+					 7800 0 0 3 &mpic 34 1
+					 7800 0 0 4 &mpic 31 1
 
 					/* IDSEL 18 */
-					 9000 0 0 1 40000 31 1
-					 9000 0 0 2 40000 32 1
-					 9000 0 0 3 40000 33 1
-					 9000 0 0 4 40000 34 1
+					 9000 0 0 1 &mpic 31 1
+					 9000 0 0 2 &mpic 32 1
+					 9000 0 0 3 &mpic 33 1
+					 9000 0 0 4 &mpic 34 1
 
 					/* IDSEL 19 */
-					 9800 0 0 1 40000 34 1
-					 9800 0 0 2 40000 31 1
-					 9800 0 0 3 40000 32 1
-					 9800 0 0 4 40000 33 1
+					 9800 0 0 1 &mpic 34 1
+					 9800 0 0 2 &mpic 31 1
+					 9800 0 0 3 &mpic 32 1
+					 9800 0 0 4 &mpic 33 1
 
 					/* IDSEL 20 */
-					 a000 0 0 1 40000 33 1
-					 a000 0 0 2 40000 34 1
-					 a000 0 0 3 40000 31 1
-					 a000 0 0 4 40000 32 1
+					 a000 0 0 1 &mpic 33 1
+					 a000 0 0 2 &mpic 34 1
+					 a000 0 0 3 &mpic 31 1
+					 a000 0 0 4 &mpic 32 1
 
 					/* IDSEL 21 */
-					 a800 0 0 1 40000 32 1
-					 a800 0 0 2 40000 33 1
-					 a800 0 0 3 40000 34 1
-					 a800 0 0 4 40000 31 1>;
+					 a800 0 0 1 &mpic 32 1
+					 a800 0 0 2 &mpic 33 1
+					 a800 0 0 3 &mpic 34 1
+					 a800 0 0 4 &mpic 31 1>;
 
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 			interrupts = <8 0>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 80000000 80000000 0 20000000
 				  01000000 0 00000000 e2000000 0 01000000>;
 		};
 
-		pic@40000 {
-			linux,phandle = <40000>;
+		mpic: pic@40000 {
 			interrupt-controller;
 			#address-cells = <0>;
 			#interrupt-cells = <2>;
-			reg = <40000 20100>;
+			reg = <40000 40000>;
 			built-in;
 			device_type = "open-pic";
 		};
 
 		cpm@e0000000 {
-			linux,phandle = <e0000000>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			#interrupt-cells = <2>;
@@ -228,13 +215,12 @@
 			command-proc = <919c0>;
 			brg-frequency = <9d5b340>;
 
-			pic@90c00 {
-				linux,phandle = <90c00>;
+			cpmpic: pic@90c00 {
 				interrupt-controller;
 				#address-cells = <0>;
 				#interrupt-cells = <2>;
 				interrupts = <1e 0>;
-				interrupt-parent = <40000>;
+				interrupt-parent = <&mpic>;
 				reg = <90c00 80>;
 				built-in;
 				device_type = "cpm-pic";
@@ -251,7 +237,7 @@
 				tx-clock = <1>;
 				current-speed = <1c200>;
 				interrupts = <28 8>;
-				interrupt-parent = <90c00>;
+				interrupt-parent = <&cpmpic>;
 			};
 
 			scc@91a20 {
@@ -265,7 +251,7 @@
 				tx-clock = <2>;
 				current-speed = <1c200>;
 				interrupts = <29 8>;
-				interrupt-parent = <90c00>;
+				interrupt-parent = <&cpmpic>;
 			};
 
 			fcc@91320 {
@@ -279,8 +265,8 @@
 				rx-clock = <15>;
 				tx-clock = <16>;
 				interrupts = <21 8>;
-				interrupt-parent = <90c00>;
-				phy-handle = <2452002>;
+				interrupt-parent = <&cpmpic>;
+				phy-handle = <&phy2>;
 			};
 
 			fcc@91340 {
@@ -294,8 +280,8 @@
 				rx-clock = <17>;
 				tx-clock = <18>;
 				interrupts = <22 8>;
-				interrupt-parent = <90c00>;
-				phy-handle = <2452003>;
+				interrupt-parent = <&cpmpic>;
+				phy-handle = <&phy3>;
 			};
 		};
 	};
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index 06d2465..bf49d8c 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -16,16 +16,14 @@
 
 / {
 	model = "MPC8568EMDS";
-	compatible = "MPC85xxMDS";
+	compatible = "MPC8568EMDS", "MPC85xxMDS";
 	#address-cells = <1>;
 	#size-cells = <1>;
-	linux,phandle = <100>;
 
 	cpus {
 		#cpus = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		linux,phandle = <200>;
 
 		PowerPC,8568@0 {
 			device_type = "cpu";
@@ -38,13 +36,11 @@
 			bus-frequency = <0>;
 			clock-frequency = <0>;
 			32-bit;
-			linux,phandle = <201>;
 		};
 	};
 
 	memory {
 		device_type = "memory";
-		linux,phandle = <300>;
 		reg = <00000000 10000000>;
 	};
 
@@ -67,7 +63,7 @@
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			interrupts = <1b 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 			dfsrr;
 		};
 
@@ -76,7 +72,7 @@
 			compatible = "fsl-i2c";
 			reg = <3100 100>;
 			interrupts = <1b 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 			dfsrr;
 		};
 
@@ -86,32 +82,26 @@
 			device_type = "mdio";
 			compatible = "gianfar";
 			reg = <24520 20>;
-			linux,phandle = <24520>;
-			ethernet-phy@0 {
-				linux,phandle = <2452000>;
-				interrupt-parent = <40000>;
+			phy0: ethernet-phy@0 {
+				interrupt-parent = <&mpic>;
 				interrupts = <31 1>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@1 {
-				linux,phandle = <2452001>;
-				interrupt-parent = <40000>;
+			phy1: ethernet-phy@1 {
+				interrupt-parent = <&mpic>;
 				interrupts = <32 1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 			};
-
-			ethernet-phy@2 {
-				linux,phandle = <2452002>;
-				interrupt-parent = <40000>;
+			phy2: ethernet-phy@2 {
+				interrupt-parent = <&mpic>;
 				interrupts = <31 1>;
 				reg = <2>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@3 {
-				linux,phandle = <2452003>;
-				interrupt-parent = <40000>;
+			phy3: ethernet-phy@3 {
+				interrupt-parent = <&mpic>;
 				interrupts = <32 1>;
 				reg = <3>;
 				device_type = "ethernet-phy";
@@ -127,8 +117,8 @@
 			reg = <24000 1000>;
 			mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <d 2 e 2 12 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452002>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy2>;
 		};
 
 		ethernet@25000 {
@@ -140,8 +130,8 @@
 			reg = <25000 1000>;
 			mac-address = [ 00 00 00 00 00 00];
 			interrupts = <13 2 14 2 18 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452003>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy3>;
 		};
 
 		serial@4500 {
@@ -150,7 +140,7 @@
 			reg = <4500 100>;
 			clock-frequency = <0>;
 			interrupts = <1a 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 		};
 
 		serial@4600 {
@@ -159,7 +149,7 @@
 			reg = <4600 100>;
 			clock-frequency = <0>;
 			interrupts = <1a 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 		};
 
 		crypto@30000 {
@@ -168,15 +158,14 @@
 			compatible = "talitos";
 			reg = <30000 f000>;
 			interrupts = <1d 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 			num-channels = <4>;
 			channel-fifo-len = <18>;
 			exec-units-mask = <000000fe>;
 			descriptor-types-mask = <012b0ebf>;
 		};
 
-		pic@40000 {
-			linux,phandle = <40000>;
+		mpic: pic@40000 {
 			clock-frequency = <0>;
 			interrupt-controller;
 			#address-cells = <0>;
@@ -192,8 +181,7 @@
 			device_type = "par_io";
 			num-ports = <7>;
 
-			ucc_pin@01 {
-				linux,phandle = <e010001>;
+			pio1: ucc_pin@01 {
 				pio-map = <
 			/* port  pin  dir  open_drain  assignment  has_irq */
 					4  0a  1  0  2  0 	/* TxD0 */
@@ -220,8 +208,7 @@
 					4  13  1  0  2  0 	/* GTX_CLK */
 					1  1f  2  0  3  0>;	/* GTX125 */
 			};
-			ucc_pin@02 {
-				linux,phandle = <e010002>;
+			pio2: ucc_pin@02 {
 				pio-map = <
 			/* port  pin  dir  open_drain  assignment  has_irq */
 					5  0a 1  0  2  0   /* TxD0 */
@@ -277,7 +264,7 @@
 			compatible = "fsl_spi";
 			reg = <4c0 40>;
 			interrupts = <2>;
-			interrupt-parent = <80>;
+			interrupt-parent = <&qeic>;
 			mode = "cpu";
 		};
 
@@ -286,7 +273,7 @@
 			compatible = "fsl_spi";
 			reg = <500 40>;
 			interrupts = <1>;
-			interrupt-parent = <80>;
+			interrupt-parent = <&qeic>;
 			mode = "cpu";
 		};
 
@@ -297,12 +284,12 @@
 			device-id = <1>;
 			reg = <2000 200>;
 			interrupts = <20>;
-			interrupt-parent = <80>;
+			interrupt-parent = <&qeic>;
 			mac-address = [ 00 04 9f 00 23 23 ];
 			rx-clock = <0>;
 			tx-clock = <19>;
-			phy-handle = <212000>;
-			pio-handle = <e010001>;
+			phy-handle = <&qe_phy0>;
+			pio-handle = <&pio1>;
 		};
 
 		ucc@3000 {
@@ -312,12 +299,12 @@
 			device-id = <2>;
 			reg = <3000 200>;
 			interrupts = <21>;
-			interrupt-parent = <80>;
+			interrupt-parent = <&qeic>;
 			mac-address = [ 00 11 22 33 44 55 ];
 			rx-clock = <0>;
 			tx-clock = <14>;
-			phy-handle = <212001>;
-			pio-handle = <e010002>;
+			phy-handle = <&qe_phy1>;
+			pio-handle = <&pio2>;
 		};
 
 		mdio@2120 {
@@ -329,33 +316,29 @@
 
 			/* These are the same PHYs as on
 			 * gianfar's MDIO bus */
-			ethernet-phy@00 {
-				linux,phandle = <212000>;
-				interrupt-parent = <40000>;
+			qe_phy0: ethernet-phy@00 {
+				interrupt-parent = <&mpic>;
 				interrupts = <31 1>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 				interface = <6>; //ENET_1000_GMII
 			};
-			ethernet-phy@01 {
-				linux,phandle = <212001>;
-				interrupt-parent = <40000>;
+			qe_phy1: ethernet-phy@01 {
+				interrupt-parent = <&mpic>;
 				interrupts = <32 1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 				interface = <6>;
 			};
-			ethernet-phy@02 {
-				linux,phandle = <212002>;
-				interrupt-parent = <40000>;
+			qe_phy2: ethernet-phy@02 {
+				interrupt-parent = <&mpic>;
 				interrupts = <31 1>;
 				reg = <2>;
 				device_type = "ethernet-phy";
 				interface = <6>; //ENET_1000_GMII
 			};
-			ethernet-phy@03 {
-				linux,phandle = <212003>;
-				interrupt-parent = <40000>;
+			qe_phy3: ethernet-phy@03 {
+				interrupt-parent = <&mpic>;
 				interrupts = <32 1>;
 				reg = <3>;
 				device_type = "ethernet-phy";
@@ -363,8 +346,7 @@
 			};
 		};
 
-		qeic@80 {
-			linux,phandle = <80>;
+		qeic: qeic@80 {
 			interrupt-controller;
 			device_type = "qeic";
 			#address-cells = <0>;
@@ -373,7 +355,7 @@
 			built-in;
 			big-endian;
 			interrupts = <1e 2 1e 2>; //high:30 low:30
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 		};
 
 	};
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index f0c7731..8a4995a 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -32,7 +32,6 @@
 			bus-frequency = <0>;		// From uboot
 			clock-frequency = <0>;		// From uboot
 			32-bit;
-			linux,boot-cpu;
 		};
 		PowerPC,8641@1 {
 			device_type = "cpu";
@@ -67,7 +66,7 @@
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			interrupts = <2b 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 			dfsrr;
 		};
 
@@ -76,7 +75,7 @@
 			compatible = "fsl-i2c";
 			reg = <3100 100>;
 			interrupts = <2b 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 			dfsrr;
 		};
 
@@ -86,31 +85,26 @@
 			device_type = "mdio";
 			compatible = "gianfar";
 			reg = <24520 20>;
-			linux,phandle = <24520>;
-			ethernet-phy@0 {
-				linux,phandle = <2452000>;
-				interrupt-parent = <40000>;
+			phy0: ethernet-phy@0 {
+				interrupt-parent = <&mpic>;
 				interrupts = <4a 1>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@1 {
-				linux,phandle = <2452001>;
-				interrupt-parent = <40000>;
+			phy1: ethernet-phy@1 {
+				interrupt-parent = <&mpic>;
 				interrupts = <4a 1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@2 {
-				linux,phandle = <2452002>;
-				interrupt-parent = <40000>;
+			phy2: ethernet-phy@2 {
+				interrupt-parent = <&mpic>;
 				interrupts = <4a 1>;
 				reg = <2>;
 				device_type = "ethernet-phy";
 			};
-			ethernet-phy@3 {
-				linux,phandle = <2452003>;
-				interrupt-parent = <40000>;
+			phy3: ethernet-phy@3 {
+				interrupt-parent = <&mpic>;
 				interrupts = <4a 1>;
 				reg = <3>;
 				device_type = "ethernet-phy";
@@ -126,8 +120,8 @@
 			reg = <24000 1000>;
 			mac-address = [ 00 E0 0C 00 73 00 ];
 			interrupts = <1d 2 1e 2 22 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452000>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy0>;
 		};
 
 		ethernet@25000 {
@@ -139,8 +133,8 @@
 			reg = <25000 1000>;
 			mac-address = [ 00 E0 0C 00 73 01 ];
 			interrupts = <23 2 24 2 28 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452001>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy1>;
 		};
 		
 		ethernet@26000 {
@@ -152,8 +146,8 @@
 			reg = <26000 1000>;
 			mac-address = [ 00 E0 0C 00 02 FD ];
 			interrupts = <1F 2 20 2 21 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452002>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy2>;
 		};
 
 		ethernet@27000 {
@@ -165,8 +159,8 @@
 			reg = <27000 1000>;
 			mac-address = [ 00 E0 0C 00 03 FD ];
 			interrupts = <25 2 26 2 27 2>;
-			interrupt-parent = <40000>;
-			phy-handle = <2452003>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy3>;
 		};
 		serial@4500 {
 			device_type = "serial";
@@ -174,7 +168,7 @@
 			reg = <4500 100>;
 			clock-frequency = <0>;
 			interrupts = <2a 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 		};
 
 		serial@4600 {
@@ -183,7 +177,7 @@
 			reg = <4600 100>;
 			clock-frequency = <0>;
 			interrupts = <1c 2>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 		};
 
 		pci@8000 {
@@ -197,103 +191,102 @@
 			ranges = <02000000 0 80000000 80000000 0 20000000
 				  01000000 0 00000000 e2000000 0 00100000>;
 			clock-frequency = <1fca055>;
-			interrupt-parent = <40000>;
+			interrupt-parent = <&mpic>;
 			interrupts = <18 2>;
 			interrupt-map-mask = <f800 0 0 7>;
 			interrupt-map = <
 				/* IDSEL 0x11 */
-				8800 0 0 1 4d0 3 2
-				8800 0 0 2 4d0 4 2
-				8800 0 0 3 4d0 5 2
-				8800 0 0 4 4d0 6 2
+				8800 0 0 1 &i8259 3 2
+				8800 0 0 2 &i8259 4 2
+				8800 0 0 3 &i8259 5 2
+				8800 0 0 4 &i8259 6 2
 
 				/* IDSEL 0x12 */
-				9000 0 0 1 4d0 4 2
-				9000 0 0 2 4d0 5 2
-				9000 0 0 3 4d0 6 2
-				9000 0 0 4 4d0 3 2
+				9000 0 0 1 &i8259 4 2
+				9000 0 0 2 &i8259 5 2
+				9000 0 0 3 &i8259 6 2
+				9000 0 0 4 &i8259 3 2
 
 				/* IDSEL 0x13 */
-				9800 0 0 1 4d0 0 0
-				9800 0 0 2 4d0 0 0
-				9800 0 0 3 4d0 0 0
-				9800 0 0 4 4d0 0 0
+				9800 0 0 1 &i8259 0 0
+				9800 0 0 2 &i8259 0 0
+				9800 0 0 3 &i8259 0 0
+				9800 0 0 4 &i8259 0 0
 
 				/* IDSEL 0x14 */
-				a000 0 0 1 4d0 0 0
-				a000 0 0 2 4d0 0 0
-				a000 0 0 3 4d0 0 0
-				a000 0 0 4 4d0 0 0
+				a000 0 0 1 &i8259 0 0
+				a000 0 0 2 &i8259 0 0
+				a000 0 0 3 &i8259 0 0
+				a000 0 0 4 &i8259 0 0
 
 				/* IDSEL 0x15 */
-				a800 0 0 1 4d0 0 0
-				a800 0 0 2 4d0 0 0
-				a800 0 0 3 4d0 0 0
-				a800 0 0 4 4d0 0 0
+				a800 0 0 1 &i8259 0 0
+				a800 0 0 2 &i8259 0 0
+				a800 0 0 3 &i8259 0 0
+				a800 0 0 4 &i8259 0 0
 
 				/* IDSEL 0x16 */
-				b000 0 0 1 4d0 0 0
-				b000 0 0 2 4d0 0 0
-				b000 0 0 3 4d0 0 0
-				b000 0 0 4 4d0 0 0
+				b000 0 0 1 &i8259 0 0
+				b000 0 0 2 &i8259 0 0
+				b000 0 0 3 &i8259 0 0
+				b000 0 0 4 &i8259 0 0
 
 				/* IDSEL 0x17 */
-				b800 0 0 1 4d0 0 0
-				b800 0 0 2 4d0 0 0
-				b800 0 0 3 4d0 0 0
-				b800 0 0 4 4d0 0 0
+				b800 0 0 1 &i8259 0 0
+				b800 0 0 2 &i8259 0 0
+				b800 0 0 3 &i8259 0 0
+				b800 0 0 4 &i8259 0 0
 
 				/* IDSEL 0x18 */
-				c000 0 0 1 4d0 0 0
-				c000 0 0 2 4d0 0 0
-				c000 0 0 3 4d0 0 0
-				c000 0 0 4 4d0 0 0
+				c000 0 0 1 &i8259 0 0
+				c000 0 0 2 &i8259 0 0
+				c000 0 0 3 &i8259 0 0
+				c000 0 0 4 &i8259 0 0
 
 				/* IDSEL 0x19 */
-				c800 0 0 1 4d0 0 0
-				c800 0 0 2 4d0 0 0
-				c800 0 0 3 4d0 0 0
-				c800 0 0 4 4d0 0 0
+				c800 0 0 1 &i8259 0 0
+				c800 0 0 2 &i8259 0 0
+				c800 0 0 3 &i8259 0 0
+				c800 0 0 4 &i8259 0 0
 
 				/* IDSEL 0x1a */
-				d000 0 0 1 4d0 6 2
-				d000 0 0 2 4d0 3 2
-				d000 0 0 3 4d0 4 2
-				d000 0 0 4 4d0 5 2
+				d000 0 0 1 &i8259 6 2
+				d000 0 0 2 &i8259 3 2
+				d000 0 0 3 &i8259 4 2
+				d000 0 0 4 &i8259 5 2
 
 
 				/* IDSEL 0x1b */
-				d800 0 0 1 4d0 5 2
-				d800 0 0 2 4d0 0 0
-				d800 0 0 3 4d0 0 0
-				d800 0 0 4 4d0 0 0
+				d800 0 0 1 &i8259 5 2
+				d800 0 0 2 &i8259 0 0
+				d800 0 0 3 &i8259 0 0
+				d800 0 0 4 &i8259 0 0
 
 				/* IDSEL 0x1c */
-				e000 0 0 1 4d0 9 2
-				e000 0 0 2 4d0 a 2
-				e000 0 0 3 4d0 c 2
-				e000 0 0 4 4d0 7 2
+				e000 0 0 1 &i8259 9 2
+				e000 0 0 2 &i8259 a 2
+				e000 0 0 3 &i8259 c 2
+				e000 0 0 4 &i8259 7 2
 
 				/* IDSEL 0x1d */
-				e800 0 0 1 4d0 9 2
-				e800 0 0 2 4d0 a 2
-				e800 0 0 3 4d0 b 2
-				e800 0 0 4 4d0 0 0
+				e800 0 0 1 &i8259 9 2
+				e800 0 0 2 &i8259 a 2
+				e800 0 0 3 &i8259 b 2
+				e800 0 0 4 &i8259 0 0
 
 				/* IDSEL 0x1e */
-				f000 0 0 1 4d0 c 2
-				f000 0 0 2 4d0 0 0
-				f000 0 0 3 4d0 0 0
-				f000 0 0 4 4d0 0 0
+				f000 0 0 1 &i8259 c 2
+				f000 0 0 2 &i8259 0 0
+				f000 0 0 3 &i8259 0 0
+				f000 0 0 4 &i8259 0 0
 
 				/* IDSEL 0x1f */
-				f800 0 0 1 4d0 6 2
-				f800 0 0 2 4d0 0 0
-				f800 0 0 3 4d0 0 0
-				f800 0 0 4 4d0 0 0
+				f800 0 0 1 &i8259 6 2
+				f800 0 0 2 &i8259 0 0
+				f800 0 0 3 &i8259 0 0
+				f800 0 0 4 &i8259 0 0
 				>;
-			i8259@4d0 {
-				linux,phandle = <4d0>;
+			i8259: i8259@4d0 {
 				clock-frequency = <0>;
 				interrupt-controller;
 				device_type = "interrupt-controller";
@@ -303,12 +296,11 @@
 				compatible = "chrp,iic";
                 	        big-endian;
 				interrupts = <49 2>;
-				interrupt-parent = <40000>;
+				interrupt-parent = <&mpic>;
 			};
 
 		};
-		pic@40000 {
-			linux,phandle = <40000>;
+		mpic: pic@40000 {
 			clock-frequency = <0>;
 			interrupt-controller;
 			#address-cells = <0>;
@@ -317,23 +309,7 @@
 			built-in;
 			compatible = "chrp,open-pic";
 			device_type = "open-pic";
-                        big-endian;
-			interrupts = <
-				10 2 11 2 12 2 13 2
-				14 2 15 2 16 2 17 2
-				18 2 19 2 1a 2 1b 2
-				1c 2 1d 2 1e 2 1f 2
-				20 2 21 2 22 2 23 2
-				24 2 25 2 26 2 27 2
-				28 2 29 2 2a 2 2b 2
-				2c 2 2d 2 2e 2 2f 2
-				30 2 31 2 32 2 33 2
-				34 2 35 2 36 2 37 2
-				38 2 39 2 2a 2 3b 2
-				3c 2 3d 2 3e 2 3f 2
-				48 1 49 2 4a 1
-				>;
-			interrupt-parent = <40000>;
+			big-endian;
 		};
 	};
 };
diff --git a/arch/powerpc/boot/dts/mpc866ads.dts b/arch/powerpc/boot/dts/mpc866ads.dts
index 5d40052..2b56b5d 100644
--- a/arch/powerpc/boot/dts/mpc866ads.dts
+++ b/arch/powerpc/boot/dts/mpc866ads.dts
@@ -37,7 +37,6 @@
 			interrupts = <f 2>;	// decrementer interrupt
 			interrupt-parent = <ff000000>;
 			linux,phandle = <201>;
-			linux,boot-cpu;
 		};
 	};
 
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts
index cf1a19f..faecd08 100644
--- a/arch/powerpc/boot/dts/mpc885ads.dts
+++ b/arch/powerpc/boot/dts/mpc885ads.dts
@@ -37,7 +37,6 @@
 			interrupts = <f 2>;	// decrementer interrupt
 			interrupt-parent = <ff000000>;
 			linux,phandle = <201>;
-			linux,boot-cpu;
 		};
 	};
 
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index e956548..2436731 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -147,6 +147,7 @@
 # CONFIG_RTAS_ERROR_LOGGING is not set
 CONFIG_RTAS_PROC=y
 CONFIG_RTAS_FLASH=y
+CONFIG_PPC_PMI=m
 CONFIG_MMIO_NVRAM=y
 # CONFIG_PPC_MPC106 is not set
 # CONFIG_PPC_970_NAP is not set
diff --git a/arch/powerpc/configs/mpc832xemds_defconfig b/arch/powerpc/configs/mpc832x_mds_defconfig
similarity index 100%
rename from arch/powerpc/configs/mpc832xemds_defconfig
rename to arch/powerpc/configs/mpc832x_mds_defconfig
diff --git a/arch/powerpc/configs/mpc8360emds_defconfig b/arch/powerpc/configs/mpc836x_mds_defconfig
similarity index 97%
rename from arch/powerpc/configs/mpc8360emds_defconfig
rename to arch/powerpc/configs/mpc836x_mds_defconfig
index bbe38cc..8eb475c 100644
--- a/arch/powerpc/configs/mpc8360emds_defconfig
+++ b/arch/powerpc/configs/mpc836x_mds_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20-rc5
-# Fri Jan 26 00:19:45 2007
+# Linux kernel version: 2.6.20
+# Sat Feb 17 10:09:26 2007
 #
 # CONFIG_PPC64 is not set
 CONFIG_PPC32=y
@@ -34,9 +34,9 @@
 CONFIG_PPC_83xx=y
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_86xx is not set
+# CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
 # CONFIG_44x is not set
-# CONFIG_8xx is not set
 # CONFIG_E200 is not set
 CONFIG_6xx=y
 CONFIG_83xx=y
@@ -63,6 +63,7 @@
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
@@ -129,10 +130,11 @@
 #
 # Platform support
 #
+# CONFIG_MPC8313_RDB is not set
 # CONFIG_MPC832x_MDS is not set
-# CONFIG_MPC834x_SYS is not set
+# CONFIG_MPC834x_MDS is not set
 # CONFIG_MPC834x_ITX is not set
-CONFIG_MPC8360E_PB=y
+CONFIG_MPC836x_MDS=y
 CONFIG_PPC_MPC836x=y
 # CONFIG_MPIC is not set
 
@@ -162,6 +164,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
@@ -171,6 +174,7 @@
 #
 # Bus options
 #
+CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_ISA_DMA=y
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
@@ -219,6 +223,7 @@
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -528,6 +533,7 @@
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
@@ -620,6 +626,7 @@
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -690,6 +697,7 @@
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PASEMI is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_I2C_SIS5595 is not set
@@ -804,6 +812,7 @@
 # HID Devices
 #
 CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
 
 #
 # USB support
@@ -868,6 +877,10 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
 # Virtualization
 #
 
@@ -1011,7 +1024,8 @@
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_PLIST=y
-CONFIG_IOMAP_COPY=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
 
 #
 # Instrumentation Support
@@ -1060,8 +1074,10 @@
 # CONFIG_CRYPTO_GF128MUL is not set
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
 # CONFIG_CRYPTO_LRW is not set
 CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -1075,6 +1091,7 @@
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
 
 #
diff --git a/arch/powerpc/configs/mpc8568mds_defconfig b/arch/powerpc/configs/mpc8568mds_defconfig
index 058e06d..7b38006 100644
--- a/arch/powerpc/configs/mpc8568mds_defconfig
+++ b/arch/powerpc/configs/mpc8568mds_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20-rc5
-# Wed Feb  7 23:54:25 2007
+# Linux kernel version: 2.6.20
+# Sat Feb 17 16:26:53 2007
 #
 # CONFIG_PPC64 is not set
 CONFIG_PPC32=y
@@ -34,9 +34,9 @@
 # CONFIG_PPC_83xx is not set
 CONFIG_PPC_85xx=y
 # CONFIG_PPC_86xx is not set
+# CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
 # CONFIG_44x is not set
-# CONFIG_8xx is not set
 # CONFIG_E200 is not set
 CONFIG_85xx=y
 CONFIG_E500=y
@@ -63,6 +63,7 @@
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
@@ -130,7 +131,7 @@
 # CONFIG_MPC8540_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC85xx_CDS is not set
-CONFIG_MPC8568_MDS=y
+CONFIG_MPC85xx_MDS=y
 CONFIG_MPC85xx=y
 CONFIG_PPC_INDIRECT_PCI_BE=y
 CONFIG_MPIC=y
@@ -162,6 +163,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
@@ -171,6 +173,7 @@
 #
 # Bus options
 #
+CONFIG_ZONE_DMA=y
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
 CONFIG_PPC_INDIRECT_PCI=y
@@ -216,6 +219,7 @@
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -301,6 +305,7 @@
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -341,7 +346,6 @@
 #
 # Misc devices
 #
-# CONFIG_TIFM_CORE is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -543,6 +547,7 @@
 # CONFIG_SERIAL_UARTLITE is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -698,6 +703,7 @@
 # HID Devices
 #
 CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
 
 #
 # USB support
@@ -760,6 +766,10 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
 # Virtualization
 #
 
@@ -896,7 +906,8 @@
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_PLIST=y
-CONFIG_IOMAP_COPY=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
 
 #
 # Instrumentation Support
@@ -914,6 +925,7 @@
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
@@ -922,7 +934,6 @@
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_RWSEMS is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -932,6 +943,8 @@
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUGGER=y
 # CONFIG_XMON is not set
 # CONFIG_BDI_SWITCH is not set
@@ -943,6 +956,8 @@
 # CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
 # CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
 # CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
+# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
+# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
 
 #
 # Security options
@@ -970,8 +985,10 @@
 # CONFIG_CRYPTO_GF128MUL is not set
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
 # CONFIG_CRYPTO_LRW is not set
 CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -985,6 +1002,7 @@
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
 
 #
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index debac66..a8da0ae 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -500,7 +500,7 @@
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
 # CONFIG_BLK_DEV_SVWKS is not set
 # CONFIG_BLK_DEV_SIIMAGE is not set
-CONFIG_BLK_DEV_SL82C105=y
+# CONFIG_BLK_DEV_SL82C105 is not set
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
@@ -646,7 +646,7 @@
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
 # CONFIG_PATA_VIA is not set
-# CONFIG_PATA_WINBOND is not set
+CONFIG_PATA_WINBOND=y
 
 #
 # Multi-device support (RAID and LVM)
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 1c794fe..6e96e50 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -483,7 +483,7 @@
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
 # CONFIG_BLK_DEV_SVWKS is not set
 # CONFIG_BLK_DEV_SIIMAGE is not set
-CONFIG_BLK_DEV_SL82C105=y
+# CONFIG_BLK_DEV_SL82C105 is not set
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
@@ -628,7 +628,7 @@
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
 # CONFIG_PATA_VIA is not set
-# CONFIG_PATA_WINBOND is not set
+CONFIG_PATA_WINBOND=y
 
 #
 # Multi-device support (RAID and LVM)
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 3e86e6e..8d52b23 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1599,6 +1599,7 @@
 
 	return pp;
 }
+EXPORT_SYMBOL(of_find_property);
 
 /*
  * Find a property with a given name for a given node
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 12c51e4..ea6fd55 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -5,6 +5,7 @@
 #include <linux/pci_regs.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
+#include <linux/etherdevice.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 
@@ -1003,3 +1004,42 @@
 	return res;
 }
 EXPORT_SYMBOL_GPL(of_irq_map_one);
+
+/**
+ * Search the device tree for the best MAC address to use.  'mac-address' is
+ * checked first, because that is supposed to contain to "most recent" MAC
+ * address. If that isn't set, then 'local-mac-address' is checked next,
+ * because that is the default address.  If that isn't set, then the obsolete
+ * 'address' is checked, just in case we're using an old device tree.
+ *
+ * Note that the 'address' property is supposed to contain a virtual address of
+ * the register set, but some DTS files have redefined that property to be the
+ * MAC address.
+ *
+ * All-zero MAC addresses are rejected, because those could be properties that
+ * exist in the device tree, but were not set by U-Boot.  For example, the
+ * DTS could define 'mac-address' and 'local-mac-address', with zero MAC
+ * addresses.  Some older U-Boots only initialized 'local-mac-address'.  In
+ * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
+ * but is all zeros.
+*/
+const void *of_get_mac_address(struct device_node *np)
+{
+	struct property *pp;
+
+	pp = of_find_property(np, "mac-address", NULL);
+	if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+		return pp->value;
+
+	pp = of_find_property(np, "local-mac-address", NULL);
+	if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+		return pp->value;
+
+	pp = of_find_property(np, "address", NULL);
+	if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+		return pp->value;
+
+	return NULL;
+}
+EXPORT_SYMBOL(of_get_mac_address);
+
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 76b5d7e..9d0735a 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -182,7 +182,7 @@
 	char *os;
 	static int display_character, set_indicator;
 	static int display_width, display_lines, form_feed;
-	const static int *row_width;
+	static const int *row_width;
 	static DEFINE_SPINLOCK(progress_lock);
 	static int current_line;
 	static int pending_newline = 0;  /* did last write end with unprinted newline? */
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 2627909..e86c37c 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -154,7 +154,7 @@
  * characteristics relative to its multiple connections.  We ignore
  * this for now.  We also assume that all cpu and memory sets have
  * their distances represented at a common level.  This won't be
- * true for heirarchical NUMA.
+ * true for hierarchical NUMA.
  *
  * In any case the ibm,associativity-reference-points should give
  * the correct depth for a normal NUMA system.
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 16e4ee1..1d44340 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -103,7 +103,7 @@
 		 *
 		 */
 		if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags,
-				      mmu_virtual_psize)) {
+				      mmu_io_psize)) {
 			printk(KERN_ERR "Failed to do bolted mapping IO "
 			       "memory at %016lx !\n", pa);
 			return -ENOMEM;
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 1aea1e6..713b31a 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -38,12 +38,12 @@
 	  Be aware that PCI initialization is the bootloader's
 	  responsibility.
 
-config MPC8360E_PB
-	bool "Freescale MPC8360E PB"
+config MPC836x_MDS
+	bool "Freescale MPC836x MDS"
 	select DEFAULT_UIMAGE
 	select QUICC_ENGINE
 	help
-	  This option enables support for the MPC836x EMDS Processor Board.
+	  This option enables support for the MPC836x MDS Processor Board.
 
 endchoice
 
@@ -69,6 +69,6 @@
 	bool
 	select PPC_UDBG_16550
 	select PPC_INDIRECT_PCI
-	default y if MPC8360E_PB
+	default y if MPC836x_MDS
 
 endmenu
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile
index 6c8199c..dfc970d 100644
--- a/arch/powerpc/platforms/83xx/Makefile
+++ b/arch/powerpc/platforms/83xx/Makefile
@@ -6,5 +6,5 @@
 obj-$(CONFIG_MPC8313_RDB)	+= mpc8313_rdb.o
 obj-$(CONFIG_MPC834x_MDS)	+= mpc834x_mds.o
 obj-$(CONFIG_MPC834x_ITX)	+= mpc834x_itx.o
-obj-$(CONFIG_MPC8360E_PB)	+= mpc8360e_pb.o
+obj-$(CONFIG_MPC836x_MDS)	+= mpc836x_mds.o
 obj-$(CONFIG_MPC832x_MDS)	+= mpc832x_mds.o
diff --git a/arch/powerpc/platforms/83xx/mpc8313_rdb.c b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
index c3b98c3..32e9e94 100644
--- a/arch/powerpc/platforms/83xx/mpc8313_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
@@ -74,16 +74,9 @@
  */
 static int __init mpc8313_rdb_probe(void)
 {
-	char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
-					  "model", NULL);
-	if (model == NULL)
-		return 0;
-	if (strcmp(model, "MPC8313ERDB"))
-		return 0;
+        unsigned long root = of_get_flat_dt_root();
 
-	DBG("MPC8313 RDB found\n");
-
-	return 1;
+        return of_flat_dt_is_compatible(root, "MPC8313ERDB");
 }
 
 define_machine(mpc8313_rdb) {
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index 3ecb55f..17e3a3c 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -57,11 +57,6 @@
 
 static u8 *bcsr_regs = NULL;
 
-u8 *get_bcsr(void)
-{
-	return bcsr_regs;
-}
-
 /* ************************************************************************
  *
  * Setup the architecture
@@ -74,17 +69,6 @@
 	if (ppc_md.progress)
 		ppc_md.progress("mpc832x_sys_setup_arch()", 0);
 
-	np = of_find_node_by_type(NULL, "cpu");
-	if (np != 0) {
-		unsigned int *fp =
-		    (int *)get_property(np, "clock-frequency", NULL);
-		if (fp != 0)
-			loops_per_jiffy = *fp / HZ;
-		else
-			loops_per_jiffy = 50000000 / HZ;
-		of_node_put(np);
-	}
-
 	/* Map BCSR area */
 	np = of_find_node_by_name(NULL, "bcsr");
 	if (np != 0) {
@@ -121,34 +105,23 @@
 		iounmap(bcsr_regs);
 		of_node_put(np);
 	}
-
 #endif				/* CONFIG_QUICC_ENGINE */
-
-#ifdef CONFIG_BLK_DEV_INITRD
-	if (initrd_start)
-		ROOT_DEV = Root_RAM0;
-	else
-#endif
-#ifdef  CONFIG_ROOT_NFS
-		ROOT_DEV = Root_NFS;
-#else
-		ROOT_DEV = Root_HDA1;
-#endif
 }
 
+static struct of_device_id mpc832x_ids[] = {
+	{ .type = "soc", },
+	{ .compatible = "soc", },
+	{ .type = "qe", },
+	{},
+};
+
 static int __init mpc832x_declare_of_platform_devices(void)
 {
-	struct device_node *np;
+	if (!machine_is(mpc832x_mds))
+		return 0;
 
-	for (np = NULL; (np = of_find_compatible_node(np, "network",
-					"ucc_geth")) != NULL;) {
-		int ucc_num;
-		char bus_id[BUS_ID_SIZE];
-
-		ucc_num = *((uint *) get_property(np, "device-id", NULL)) - 1;
-		snprintf(bus_id, BUS_ID_SIZE, "ucc_geth.%u", ucc_num);
-		of_platform_device_create(np, bus_id, NULL);
-	}
+	/* Publish the QE devices */
+	of_platform_bus_probe(NULL, mpc832x_ids, NULL);
 
 	return 0;
 }
@@ -156,7 +129,6 @@
 
 static void __init mpc832x_sys_init_IRQ(void)
 {
-
 	struct device_node *np;
 
 	np = of_find_node_by_type(NULL, "ipic");
@@ -189,6 +161,9 @@
 {
 	struct timespec tv;
 
+	if (!machine_is(mpc832x_mds))
+		return 0;
+
 	ppc_md.get_rtc_time = ds1374_get_rtc_time;
 	ppc_md.set_rtc_time = ds1374_set_rtc_time;
 
@@ -207,17 +182,9 @@
  */
 static int __init mpc832x_sys_probe(void)
 {
-	char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
-					  "model", NULL);
+        unsigned long root = of_get_flat_dt_root();
 
-	if (model == NULL)
-		return 0;
-	if (strcmp(model, "MPC8323EMDS"))
-		return 0;
-
-	DBG("%s found\n", model);
-
-	return 1;
+        return of_flat_dt_is_compatible(root, "MPC832xMDS");
 }
 
 define_machine(mpc832x_mds) {
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
index 443a317..3c009f6 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_itx.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -55,28 +55,12 @@
 	if (ppc_md.progress)
 		ppc_md.progress("mpc834x_itx_setup_arch()", 0);
 
-	np = of_find_node_by_type(NULL, "cpu");
-	if (np != 0) {
-		const unsigned int *fp =
-			get_property(np, "clock-frequency", NULL);
-		if (fp != 0)
-			loops_per_jiffy = *fp / HZ;
-		else
-			loops_per_jiffy = 50000000 / HZ;
-		of_node_put(np);
-	}
 #ifdef CONFIG_PCI
 	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
 		add_bridge(np);
 
 	ppc_md.pci_exclude_device = mpc83xx_exclude_device;
 #endif
-
-#ifdef  CONFIG_ROOT_NFS
-	ROOT_DEV = Root_NFS;
-#else
-	ROOT_DEV = Root_HDA1;
-#endif
 }
 
 static void __init mpc834x_itx_init_IRQ(void)
@@ -100,10 +84,9 @@
  */
 static int __init mpc834x_itx_probe(void)
 {
-	/* We always match for now, eventually we should look at the flat
-	   dev tree to ensure this is the board we are suppose to run on
-	*/
-	return 1;
+        unsigned long root = of_get_flat_dt_root();
+
+        return of_flat_dt_is_compatible(root, "MPC834xMITX");
 }
 
 define_machine(mpc834x_itx) {
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c
index d2736da..e5d8191 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c
@@ -125,17 +125,6 @@
 	if (ppc_md.progress)
 		ppc_md.progress("mpc834x_mds_setup_arch()", 0);
 
-	np = of_find_node_by_type(NULL, "cpu");
-	if (np != 0) {
-		const unsigned int *fp =
-			get_property(np, "clock-frequency", NULL);
-		if (fp != 0)
-			loops_per_jiffy = *fp / HZ;
-		else
-			loops_per_jiffy = 50000000 / HZ;
-		of_node_put(np);
-	}
-
 #ifdef CONFIG_PCI
 	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
 		add_bridge(np);
@@ -144,12 +133,6 @@
 #endif
 
 	mpc834x_usb_cfg();
-
-#ifdef  CONFIG_ROOT_NFS
-	ROOT_DEV = Root_NFS;
-#else
-	ROOT_DEV = Root_HDA1;
-#endif
 }
 
 static void __init mpc834x_mds_init_IRQ(void)
@@ -176,6 +159,9 @@
 {
 	struct timespec tv;
 
+	if (!machine_is(mpc834x_mds))
+		return 0;
+
 	ppc_md.get_rtc_time = ds1374_get_rtc_time;
 	ppc_md.set_rtc_time = ds1374_set_rtc_time;
 
@@ -194,10 +180,9 @@
  */
 static int __init mpc834x_mds_probe(void)
 {
-	/* We always match for now, eventually we should look at the flat
-	   dev tree to ensure this is the board we are suppose to run on
-	*/
-	return 1;
+        unsigned long root = of_get_flat_dt_root();
+
+        return of_flat_dt_is_compatible(root, "MPC834xMDS");
 }
 
 define_machine(mpc834x_mds) {
diff --git a/arch/powerpc/platforms/83xx/mpc8360e_pb.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
similarity index 67%
rename from arch/powerpc/platforms/83xx/mpc8360e_pb.c
rename to arch/powerpc/platforms/83xx/mpc836x_mds.c
index ccce2f9..526ed09 100644
--- a/arch/powerpc/platforms/83xx/mpc8360e_pb.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -5,12 +5,12 @@
  *	   Yin Olivia <Hong-hua.Yin@freescale.com>
  *
  * Description:
- * MPC8360E MDS PB board specific routines.
+ * MPC8360E MDS board specific routines.
  *
  * Changelog:
  * Jun 21, 2006	Initial version
  *
- * This program is free software; you can redistribute  it and/or modify it
+ * 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.
@@ -62,33 +62,17 @@
 
 static u8 *bcsr_regs = NULL;
 
-u8 *get_bcsr(void)
-{
-	return bcsr_regs;
-}
-
 /* ************************************************************************
  *
  * Setup the architecture
  *
  */
-static void __init mpc8360_sys_setup_arch(void)
+static void __init mpc836x_mds_setup_arch(void)
 {
 	struct device_node *np;
 
 	if (ppc_md.progress)
-		ppc_md.progress("mpc8360_sys_setup_arch()", 0);
-
-	np = of_find_node_by_type(NULL, "cpu");
-	if (np != 0) {
-		const unsigned int *fp =
-		    get_property(np, "clock-frequency", NULL);
-		if (fp != 0)
-			loops_per_jiffy = *fp / HZ;
-		else
-			loops_per_jiffy = 50000000 / HZ;
-		of_node_put(np);
-	}
+		ppc_md.progress("mpc836x_mds_setup_arch()", 0);
 
 	/* Map BCSR area */
 	np = of_find_node_by_name(NULL, "bcsr");
@@ -128,40 +112,29 @@
 	}
 
 #endif				/* CONFIG_QUICC_ENGINE */
-
-#ifdef CONFIG_BLK_DEV_INITRD
-	if (initrd_start)
-		ROOT_DEV = Root_RAM0;
-	else
-#endif
-#ifdef  CONFIG_ROOT_NFS
-		ROOT_DEV = Root_NFS;
-#else
-		ROOT_DEV = Root_HDA1;
-#endif
 }
 
-static int __init mpc8360_declare_of_platform_devices(void)
+static struct of_device_id mpc836x_ids[] = {
+	{ .type = "soc", },
+	{ .compatible = "soc", },
+	{ .type = "qe", },
+	{},
+};
+
+static int __init mpc836x_declare_of_platform_devices(void)
 {
-	struct device_node *np;
+	if (!machine_is(mpc836x_mds))
+		return 0;
 
-	for (np = NULL; (np = of_find_compatible_node(np, "network",
-					"ucc_geth")) != NULL;) {
-		int ucc_num;
-		char bus_id[BUS_ID_SIZE];
-
-		ucc_num = *((uint *) get_property(np, "device-id", NULL)) - 1;
-		snprintf(bus_id, BUS_ID_SIZE, "ucc_geth.%u", ucc_num);
-		of_platform_device_create(np, bus_id, NULL);
-	}
+	/* Publish the QE devices */
+	of_platform_bus_probe(NULL, mpc836x_ids, NULL);
 
 	return 0;
 }
-device_initcall(mpc8360_declare_of_platform_devices);
+device_initcall(mpc836x_declare_of_platform_devices);
 
-static void __init mpc8360_sys_init_IRQ(void)
+static void __init mpc836x_mds_init_IRQ(void)
 {
-
 	struct device_node *np;
 
 	np = of_find_node_by_type(NULL, "ipic");
@@ -194,6 +167,9 @@
 {
 	struct timespec tv;
 
+	if (!machine_is(mpc836x_mds))
+		return 0;
+
 	ppc_md.get_rtc_time = ds1374_get_rtc_time;
 	ppc_md.set_rtc_time = ds1374_set_rtc_time;
 
@@ -210,28 +186,21 @@
 /*
  * Called very early, MMU is off, device-tree isn't unflattened
  */
-static int __init mpc8360_sys_probe(void)
+static int __init mpc836x_mds_probe(void)
 {
-	char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
-					  "model", NULL);
-	if (model == NULL)
-		return 0;
-	if (strcmp(model, "MPC8360EPB"))
-		return 0;
+        unsigned long root = of_get_flat_dt_root();
 
-	DBG("MPC8360EMDS-PB found\n");
-
-	return 1;
+        return of_flat_dt_is_compatible(root, "MPC836xMDS");
 }
 
-define_machine(mpc8360_sys) {
-	.name 		= "MPC8360E PB",
-	.probe 		= mpc8360_sys_probe,
-	.setup_arch 	= mpc8360_sys_setup_arch,
-	.init_IRQ 	= mpc8360_sys_init_IRQ,
-	.get_irq 	= ipic_get_irq,
-	.restart 	= mpc83xx_restart,
-	.time_init 	= mpc83xx_time_init,
+define_machine(mpc836x_mds) {
+	.name		= "MPC836x MDS",
+	.probe		= mpc836x_mds_probe,
+	.setup_arch	= mpc836x_mds_setup_arch,
+	.init_IRQ	= mpc836x_mds_init_IRQ,
+	.get_irq	= ipic_get_irq,
+	.restart	= mpc83xx_restart,
+	.time_init	= mpc83xx_time_init,
 	.calibrate_decr	= generic_calibrate_decr,
-	.progress 	= udbg_progress,
+	.progress	= udbg_progress,
 };
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 0efdd2f..eb661cc 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -23,12 +23,12 @@
 	help
 	  This option enables support for the MPC85xx CDS board
 
-config MPC8568_MDS
-	bool "Freescale MPC8568 MDS"
+config MPC85xx_MDS
+	bool "Freescale MPC85xx MDS"
 	select DEFAULT_UIMAGE
 #	select QUICC_ENGINE
 	help
-	  This option enables support for the MPC8568 MDS board
+	  This option enables support for the MPC85xx MDS board
 
 endchoice
 
@@ -47,7 +47,7 @@
 	bool
 	select PPC_UDBG_16550
 	select PPC_INDIRECT_PCI
-	default y if MPC8540_ADS || MPC85xx_CDS || MPC8560_ADS || MPC8568_MDS
+	default y if MPC8540_ADS || MPC85xx_CDS || MPC8560_ADS || MPC85xx_MDS
 
 config PPC_INDIRECT_PCI_BE
 	bool
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index e40e521..4e63917 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -5,4 +5,4 @@
 obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
 obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
 obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
-obj-$(CONFIG_MPC8568_MDS) += mpc8568_mds.o
+obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index c56fce5..8ed034a 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -17,7 +17,6 @@
 #include <linux/kdev_t.h>
 #include <linux/delay.h>
 #include <linux/seq_file.h>
-#include <linux/root_dev.h>
 
 #include <asm/system.h>
 #include <asm/time.h>
@@ -245,12 +244,6 @@
 		add_bridge(np);
 	ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 #endif
-
-#ifdef  CONFIG_ROOT_NFS
-	ROOT_DEV = Root_NFS;
-#else
-	ROOT_DEV = Root_HDA1;
-#endif
 }
 
 static void mpc85xx_ads_show_cpuinfo(struct seq_file *m)
@@ -279,10 +272,9 @@
  */
 static int __init mpc85xx_ads_probe(void)
 {
-	/* We always match for now, eventually we should look at the flat
-	   dev tree to ensure this is the board we are suppose to run on
-	*/
-	return 1;
+        unsigned long root = of_get_flat_dt_root();
+
+        return of_flat_dt_is_compatible(root, "MPC85xxADS");
 }
 
 define_machine(mpc85xx_ads) {
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index abc0aca..4232686 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -22,7 +22,6 @@
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/seq_file.h>
-#include <linux/root_dev.h>
 #include <linux/initrd.h>
 #include <linux/module.h>
 #include <linux/fsl_devices.h>
@@ -263,12 +262,6 @@
 	ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup;
 	ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 #endif
-
-#ifdef  CONFIG_ROOT_NFS
-	ROOT_DEV = Root_NFS;
-#else
-	ROOT_DEV = Root_HDA1;
-#endif
 }
 
 static void mpc85xx_cds_show_cpuinfo(struct seq_file *m)
@@ -298,11 +291,9 @@
  */
 static int __init mpc85xx_cds_probe(void)
 {
-	/* We always match for now, eventually we should look at
-	 * the flat dev tree to ensure this is the board we are
-	 * supposed to run on
-	 */
-	return 1;
+        unsigned long root = of_get_flat_dt_root();
+
+        return of_flat_dt_is_compatible(root, "MPC85xxCDS");
 }
 
 define_machine(mpc85xx_cds) {
diff --git a/arch/powerpc/platforms/85xx/mpc8568_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
similarity index 84%
rename from arch/powerpc/platforms/85xx/mpc8568_mds.c
rename to arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 0861d11..81144d2 100644
--- a/arch/powerpc/platforms/85xx/mpc8568_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -8,7 +8,7 @@
  *	   Yin Olivia <Hong-hua.Yin@freescale.com>
  *
  * Description:
- * MPC8568E MDS PB board specific routines.
+ * MPC85xx MDS board specific routines.
  *
  * 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
@@ -27,7 +27,6 @@
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/seq_file.h>
-#include <linux/root_dev.h>
 #include <linux/initrd.h>
 #include <linux/module.h>
 #include <linux/fsl_devices.h>
@@ -70,14 +69,13 @@
  * Setup the architecture
  *
  */
-static void __init mpc8568_mds_setup_arch(void)
+static void __init mpc85xx_mds_setup_arch(void)
 {
 	struct device_node *np;
 	static u8 *bcsr_regs = NULL;
 
-
 	if (ppc_md.progress)
-		ppc_md.progress("mpc8568_mds_setup_arch()", 0);
+		ppc_md.progress("mpc85xx_mds_setup_arch()", 0);
 
 	np = of_find_node_by_type(NULL, "cpu");
 	if (np != NULL) {
@@ -145,26 +143,26 @@
 #endif	/* CONFIG_QUICC_ENGINE */
 }
 
-static struct of_device_id mpc8568_ids[] = {
+static struct of_device_id mpc85xx_ids[] = {
 	{ .type = "soc", },
 	{ .compatible = "soc", },
 	{ .type = "qe", },
 	{},
 };
 
-static int __init mpc8568_publish_devices(void)
+static int __init mpc85xx_publish_devices(void)
 {
-	if (!machine_is(mpc8568_mds))
+	if (!machine_is(mpc85xx_mds))
 		return 0;
 
 	/* Publish the QE devices */
-	of_platform_bus_probe(NULL,mpc8568_ids,NULL);
+	of_platform_bus_probe(NULL,mpc85xx_ids,NULL);
 
 	return 0;
 }
-device_initcall(mpc8568_publish_devices);
+device_initcall(mpc85xx_publish_devices);
 
-static void __init mpc8568_mds_pic_init(void)
+static void __init mpc85xx_mds_pic_init(void)
 {
 	struct mpic *mpic;
 	struct resource r;
@@ -207,7 +205,6 @@
 
 	mpic_init(mpic);
 
-
 #ifdef CONFIG_QUICC_ENGINE
 	np = of_find_node_by_type(NULL, "qeic");
 	if (!np)
@@ -218,27 +215,18 @@
 #endif				/* CONFIG_QUICC_ENGINE */
 }
 
-
-static int __init mpc8568_mds_probe(void)
+static int __init mpc85xx_mds_probe(void)
 {
-	char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
-					  "model", NULL);
-	if (model == NULL)
-		return 0;
-	if (strcmp(model, "MPC8568EMDS"))
-		return 0;
+        unsigned long root = of_get_flat_dt_root();
 
-	DBG("MPC8568EMDS found\n");
-
-	return 1;
+        return of_flat_dt_is_compatible(root, "MPC85xxMDS");
 }
 
-
-define_machine(mpc8568_mds) {
-	.name		= "MPC8568E MDS",
-	.probe		= mpc8568_mds_probe,
-	.setup_arch	= mpc8568_mds_setup_arch,
-	.init_IRQ	= mpc8568_mds_pic_init,
+define_machine(mpc85xx_mds) {
+	.name		= "MPC85xx MDS",
+	.probe		= mpc85xx_mds_probe,
+	.setup_arch	= mpc85xx_mds_setup_arch,
+	.init_IRQ	= mpc85xx_mds_pic_init,
 	.get_irq	= mpic_get_irq,
 	.restart	= mpc85xx_restart,
 	.calibrate_decr	= generic_calibrate_decr,
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index f4dd5f2..f42f801 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -18,7 +18,6 @@
 #include <linux/kdev_t.h>
 #include <linux/delay.h>
 #include <linux/seq_file.h>
-#include <linux/root_dev.h>
 
 #include <asm/system.h>
 #include <asm/time.h>
@@ -120,6 +119,8 @@
 	DBG("mpc86xxhpcn: cascade mapped to irq %d\n", cascade_irq);
 
 	i8259_init(cascade_node, 0);
+	of_node_put(cascade_node);
+
 	set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade);
 #endif
 }
@@ -365,12 +366,6 @@
 
 	printk("MPC86xx HPCN board from Freescale Semiconductor\n");
 
-#ifdef  CONFIG_ROOT_NFS
-	ROOT_DEV = Root_NFS;
-#else
-	ROOT_DEV = Root_HDA1;
-#endif
-
 #ifdef CONFIG_SMP
 	mpc86xx_smp_init();
 #endif
diff --git a/arch/powerpc/platforms/celleb/Makefile b/arch/powerpc/platforms/celleb/Makefile
index 3baf658..f4f8252 100644
--- a/arch/powerpc/platforms/celleb/Makefile
+++ b/arch/powerpc/platforms/celleb/Makefile
@@ -1,9 +1,8 @@
 obj-y				+= interrupt.o iommu.o setup.o \
 				   htab.o beat.o pci.o \
-				   scc_epci.o hvCall.o
+				   scc_epci.o scc_uhc.o hvCall.o
 
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_PPC_UDBG_BEAT)	+= udbg_beat.o
-obj-$(CONFIG_USB)		+= scc_uhc.o
 obj-$(CONFIG_HAS_TXX9_SERIAL)	+= scc_sio.o
 obj-$(CONFIG_SPU_BASE)		+= spu_priv1.o
diff --git a/arch/powerpc/platforms/celleb/setup.c b/arch/powerpc/platforms/celleb/setup.c
index 1de63ac..5f4d0d9 100644
--- a/arch/powerpc/platforms/celleb/setup.c
+++ b/arch/powerpc/platforms/celleb/setup.c
@@ -137,10 +137,12 @@
 	return -ENODEV;
 }
 
+#ifdef CONFIG_KEXEC
 static void celleb_kexec_cpu_down(int crash, int secondary)
 {
 	beatic_deinit_IRQ();
 }
+#endif
 
 static struct of_device_id celleb_bus_ids[] = {
 	{ .type = "scc", },
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 4be3943..d270a1e 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -62,4 +62,14 @@
 	  This support is required for graphics and sound. In
 	  general, all users will say Y or M.
 
+config PS3_SYS_MANAGER
+	bool "PS3 System Manager driver"
+	select PS3_VUART
+	default y
+	help
+	  Include support for the PS3 System Manager.
+
+	  This support is required for system control.  In
+	  general, all users will say Y.
+
 endmenu
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 13d669a..ac5df96 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -42,6 +42,10 @@
 #define DBG(fmt...) do{if(0)printk(fmt);}while(0)
 #endif
 
+#if !defined(CONFIG_SMP)
+static void smp_send_stop(void) {}
+#endif
+
 int ps3_get_firmware_version(union ps3_firmware_version *v)
 {
 	int result = lv1_get_version_info(&v->raw);
@@ -66,22 +70,35 @@
 	lv1_pause(0);
 }
 
+static void ps3_restart(char *cmd)
+{
+	DBG("%s:%d cmd '%s'\n", __func__, __LINE__, cmd);
+
+	smp_send_stop();
+	ps3_sys_manager_restart(); /* never returns */
+}
+
+static void ps3_power_off(void)
+{
+	DBG("%s:%d\n", __func__, __LINE__);
+
+	smp_send_stop();
+	ps3_sys_manager_power_off(); /* never returns */
+}
+
 static void ps3_panic(char *str)
 {
 	DBG("%s:%d %s\n", __func__, __LINE__, str);
 
-#ifdef CONFIG_SMP
 	smp_send_stop();
-#endif
 	printk("\n");
 	printk("   System does not reboot automatically.\n");
 	printk("   Please press POWER button.\n");
 	printk("\n");
 
-	for (;;) ;
+	while(1);
 }
 
-
 static void prealloc(struct ps3_prealloc *p)
 {
 	if (!p->size)
@@ -219,6 +236,8 @@
 	.get_rtc_time			= ps3_get_rtc_time,
 	.calibrate_decr			= ps3_calibrate_decr,
 	.progress			= ps3_progress,
+	.restart			= ps3_restart,
+	.power_off			= ps3_power_off,
 #if defined(CONFIG_KEXEC)
 	.kexec_cpu_down			= ps3_kexec_cpu_down,
 	.machine_kexec			= ps3_machine_kexec,
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index dc0583b..2dfd050 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -4,7 +4,7 @@
 
 obj-y			:= pci.o lpar.o hvCall.o nvram.o reconfig.o \
 			   setup.o iommu.o ras.o rtasd.o pci_dlpar.o \
-			   firmware.o
+			   firmware.o power.o
 obj-$(CONFIG_SMP)	+= smp.o
 obj-$(CONFIG_XICS)	+= xics.o
 obj-$(CONFIG_SCANLOG)	+= scanlog.o
diff --git a/arch/powerpc/platforms/pseries/power.c b/arch/powerpc/platforms/pseries/power.c
new file mode 100644
index 0000000..2624b71
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/power.c
@@ -0,0 +1,87 @@
+/*
+ *  Interface for power-management for ppc64 compliant platform
+ *
+ *  Manish Ahuja <mahuja@us.ibm.com>
+ *
+ *  Feb 2007
+ *
+ *  Copyright (C) 2007 IBM Corporation.
+ *
+ *  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; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kobject.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+unsigned long rtas_poweron_auto; /* default and normal state is 0 */
+
+static ssize_t auto_poweron_show(struct subsystem *subsys, char *buf)
+{
+        return sprintf(buf, "%lu\n", rtas_poweron_auto);
+}
+
+static ssize_t
+auto_poweron_store(struct subsystem *subsys, const char *buf, size_t n)
+{
+	int ret;
+	unsigned long ups_restart;
+	ret = sscanf(buf, "%lu", &ups_restart);
+
+	if ((ret == 1) && ((ups_restart == 1) || (ups_restart == 0))){
+		rtas_poweron_auto = ups_restart;
+		return n;
+	}
+	return -EINVAL;
+}
+
+static struct subsys_attribute auto_poweron_attr = {
+        .attr   = {
+                .name = __stringify(auto_poweron),
+                .mode = 0644,
+        },
+        .show   = auto_poweron_show,
+        .store  = auto_poweron_store,
+};
+
+#ifndef CONFIG_PM
+decl_subsys(power,NULL,NULL);
+
+static struct attribute *g[] = {
+        &auto_poweron_attr.attr,
+        NULL,
+};
+
+static struct attribute_group attr_group = {
+        .attrs = g,
+};
+
+static int __init pm_init(void)
+{
+        int error = subsystem_register(&power_subsys);
+        if (!error)
+                error = sysfs_create_group(&power_subsys.kset.kobj,&attr_group);
+        return error;
+}
+core_initcall(pm_init);
+#else
+extern struct subsystem power_subsys;
+
+static int __init apo_pm_init(void)
+{
+	return (subsys_create_file(&power_subsys, &auto_poweron_attr));
+}
+__initcall(apo_pm_init);
+#endif
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index b43f139..22bc019 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -29,8 +29,11 @@
 extern void setup_kexec_cpu_down_xics(void);
 extern void setup_kexec_cpu_down_mpic(void);
 #else
-static inline setup_kexec_cpu_down_xics(void) { };
-static inline setup_kexec_cpu_down_mpic(void) { };
+static inline void setup_kexec_cpu_down_xics(void) { }
+static inline void setup_kexec_cpu_down_mpic(void) { }
 #endif
 
+/* Poweron flag used for enabling auto ups restart */
+extern unsigned long rtas_poweron_auto;
+
 #endif /* _PSERIES_PSERIES_H */
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 435a045..34aff47 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -486,6 +486,34 @@
 	return PCI_PROBE_NORMAL;
 }
 
+/**
+ * pSeries_power_off - tell firmware about how to power off the system.
+ *
+ * This function calls either the power-off rtas token in normal cases
+ * or the ibm,power-off-ups token (if present & requested) in case of
+ * a power failure. If power-off token is used, power on will only be
+ * possible with power button press. If ibm,power-off-ups token is used
+ * it will allow auto poweron after power is restored.
+ */
+void pSeries_power_off(void)
+{
+	int rc;
+	int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups");
+
+	if (rtas_flash_term_hook)
+		rtas_flash_term_hook(SYS_POWER_OFF);
+
+	if (rtas_poweron_auto == 0 ||
+		rtas_poweroff_ups_token == RTAS_UNKNOWN_SERVICE) {
+		rc = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
+		printk(KERN_INFO "RTAS power-off returned %d\n", rc);
+	} else {
+		rc = rtas_call(rtas_poweroff_ups_token, 0, 1, NULL);
+		printk(KERN_INFO "RTAS ibm,power-off-ups returned %d\n", rc);
+	}
+	for (;;);
+}
+
 define_machine(pseries) {
 	.name			= "pSeries",
 	.probe			= pSeries_probe,
@@ -496,7 +524,7 @@
 	.pcibios_fixup		= pSeries_final_fixup,
 	.pci_probe_mode		= pSeries_pci_probe_mode,
 	.restart		= rtas_restart,
-	.power_off		= rtas_power_off,
+	.power_off		= pSeries_power_off,
 	.halt			= rtas_halt,
 	.panic			= rtas_os_term,
 	.get_boot_time		= rtas_get_boot_time,
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 85dcdf1..26ca3ff 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -7,6 +7,7 @@
 obj-$(CONFIG_PPC_MPC106)	+= grackle.o
 obj-$(CONFIG_PPC_DCR)		+= dcr.o
 obj-$(CONFIG_PPC_DCR_NATIVE)	+= dcr-low.o
+obj-$(CONFIG_PPC_PMI)		+= pmi.o
 obj-$(CONFIG_U3_DART)		+= dart_iommu.o
 obj-$(CONFIG_MMIO_NVRAM)	+= mmio_nvram.o
 obj-$(CONFIG_FSL_SOC)		+= fsl_soc.o
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 34161bc..d20f0292 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -233,14 +233,7 @@
 			goto err;
 		}
 
-		mac_addr = get_property(np, "local-mac-address", NULL);
-		if (mac_addr == NULL)
-			mac_addr = get_property(np, "mac-address", NULL);
-		if (mac_addr == NULL) {
-			/* Obsolete */
-			mac_addr = get_property(np, "address", NULL);
-		}
-
+		mac_addr = of_get_mac_address(np);
 		if (mac_addr)
 			memcpy(gfar_data.mac_addr, mac_addr, 6);
 
@@ -646,8 +639,9 @@
 			goto unreg;
 		}
 
-		mac_addr = get_property(np, "mac-address", NULL);
-		memcpy(fs_enet_data.macaddr, mac_addr, 6);
+		mac_addr = of_get_mac_address(np);
+		if (mac_addr)
+			memcpy(fs_enet_data.macaddr, mac_addr, 6);
 
 		ph = get_property(np, "phy-handle", NULL);
 		phy = of_find_node_by_phandle(*ph);
@@ -931,8 +925,9 @@
 			goto err;
 		r[0].name = enet_regs;
 
-		mac_addr = (void *)get_property(np, "mac-address", NULL);
-		memcpy(fs_enet_data.macaddr, mac_addr, 6);
+		mac_addr = of_get_mac_address(np);
+		if (mac_addr)
+			memcpy(fs_enet_data.macaddr, mac_addr, 6);
 
 		ph = (phandle *) get_property(np, "phy-handle", NULL);
 		if (ph != NULL)
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 4e54a09..bcfb900 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1370,7 +1370,7 @@
 			printk(KERN_ERR "Failed to map IPI %d\n", i);
 			break;
 		}
-		request_irq(vipi, mpic_ipi_action, IRQF_DISABLED,
+		request_irq(vipi, mpic_ipi_action, IRQF_DISABLED|IRQF_PERCPU,
 			    ipi_names[i], mpic);
 	}
 }
diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c
new file mode 100644
index 0000000..a528201
--- /dev/null
+++ b/arch/powerpc/sysdev/pmi.c
@@ -0,0 +1,305 @@
+/*
+ * pmi driver
+ *
+ * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
+ *
+ * PMI (Platform Management Interrupt) is a way to communicate
+ * with the BMC (Baseboard Management Controller) via interrupts.
+ * Unlike IPMI it is bidirectional and has a low latency.
+ *
+ * Author: Christian Krafft <krafft@de.ibm.com>
+ *
+ * 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, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+
+#include <asm/of_device.h>
+#include <asm/of_platform.h>
+#include <asm/io.h>
+#include <asm/pmi.h>
+
+
+struct pmi_data {
+	struct list_head	handler;
+	spinlock_t		handler_spinlock;
+	spinlock_t		pmi_spinlock;
+	struct mutex		msg_mutex;
+	pmi_message_t		msg;
+	struct completion	*completion;
+	struct of_device	*dev;
+	int			irq;
+	u8 __iomem		*pmi_reg;
+	struct work_struct	work;
+};
+
+
+
+static void __iomem *of_iomap(struct device_node *np)
+{
+	struct resource res;
+
+	if (of_address_to_resource(np, 0, &res))
+		return NULL;
+
+	pr_debug("Resource start: 0x%lx\n", res.start);
+	pr_debug("Resource end: 0x%lx\n", res.end);
+
+	return ioremap(res.start, 1 + res.end - res.start);
+}
+
+
+static int pmi_irq_handler(int irq, void *dev_id)
+{
+	struct pmi_data *data;
+	u8 type;
+	int rc;
+
+	data = dev_id;
+
+	spin_lock(&data->pmi_spinlock);
+
+	type = ioread8(data->pmi_reg + PMI_READ_TYPE);
+	pr_debug("pmi: got message of type %d\n", type);
+
+	if (type & PMI_ACK && !data->completion) {
+		printk(KERN_WARNING "pmi: got unexpected ACK message.\n");
+		rc = -EIO;
+		goto unlock;
+	}
+
+	if (data->completion && !(type & PMI_ACK)) {
+		printk(KERN_WARNING "pmi: expected ACK, but got %d\n", type);
+		rc = -EIO;
+		goto unlock;
+	}
+
+	data->msg.type = type;
+	data->msg.data0 = ioread8(data->pmi_reg + PMI_READ_DATA0);
+	data->msg.data1 = ioread8(data->pmi_reg + PMI_READ_DATA1);
+	data->msg.data2 = ioread8(data->pmi_reg + PMI_READ_DATA2);
+	rc = 0;
+unlock:
+	spin_unlock(&data->pmi_spinlock);
+
+	if (rc == -EIO) {
+		rc = IRQ_HANDLED;
+		goto out;
+	}
+
+	if (data->msg.type & PMI_ACK) {
+		complete(data->completion);
+		rc = IRQ_HANDLED;
+		goto out;
+	}
+
+	schedule_work(&data->work);
+
+	rc = IRQ_HANDLED;
+out:
+	return rc;
+}
+
+
+static struct of_device_id pmi_match[] = {
+	{ .type = "ibm,pmi", .name = "ibm,pmi" },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, pmi_match);
+
+static void pmi_notify_handlers(struct work_struct *work)
+{
+	struct pmi_data *data;
+	struct pmi_handler *handler;
+
+	data = container_of(work, struct pmi_data, work);
+
+	spin_lock(&data->handler_spinlock);
+	list_for_each_entry(handler, &data->handler, node) {
+		pr_debug(KERN_INFO "pmi: notifying handler %p\n", handler);
+		if (handler->type == data->msg.type)
+			handler->handle_pmi_message(data->dev, data->msg);
+	}
+	spin_unlock(&data->handler_spinlock);
+}
+
+static int pmi_of_probe(struct of_device *dev,
+			const struct of_device_id *match)
+{
+	struct device_node *np = dev->node;
+	struct pmi_data *data;
+	int rc;
+
+	data = kzalloc(sizeof(struct pmi_data), GFP_KERNEL);
+	if (!data) {
+		printk(KERN_ERR "pmi: could not allocate memory.\n");
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	data->pmi_reg = of_iomap(np);
+	if (!data->pmi_reg) {
+		printk(KERN_ERR "pmi: invalid register address.\n");
+		rc = -EFAULT;
+		goto error_cleanup_data;
+	}
+
+	INIT_LIST_HEAD(&data->handler);
+
+	mutex_init(&data->msg_mutex);
+	spin_lock_init(&data->pmi_spinlock);
+	spin_lock_init(&data->handler_spinlock);
+
+	INIT_WORK(&data->work, pmi_notify_handlers);
+
+	dev->dev.driver_data = data;
+	data->dev = dev;
+
+	data->irq = irq_of_parse_and_map(np, 0);
+	if (data->irq == NO_IRQ) {
+		printk(KERN_ERR "pmi: invalid interrupt.\n");
+		rc = -EFAULT;
+		goto error_cleanup_iomap;
+	}
+
+	rc = request_irq(data->irq, pmi_irq_handler, 0, "pmi", data);
+	if (rc) {
+		printk(KERN_ERR "pmi: can't request IRQ %d: returned %d\n",
+				data->irq, rc);
+		goto error_cleanup_iomap;
+	}
+
+	printk(KERN_INFO "pmi: found pmi device at addr %p.\n", data->pmi_reg);
+
+	goto out;
+
+error_cleanup_iomap:
+	iounmap(data->pmi_reg);
+
+error_cleanup_data:
+	kfree(data);
+
+out:
+	return rc;
+}
+
+static int pmi_of_remove(struct of_device *dev)
+{
+	struct pmi_data *data;
+	struct pmi_handler *handler, *tmp;
+
+	data = dev->dev.driver_data;
+
+	free_irq(data->irq, data);
+	iounmap(data->pmi_reg);
+
+	spin_lock(&data->handler_spinlock);
+
+	list_for_each_entry_safe(handler, tmp, &data->handler, node)
+		list_del(&handler->node);
+
+	spin_unlock(&data->handler_spinlock);
+
+	kfree(dev->dev.driver_data);
+
+	return 0;
+}
+
+static struct of_platform_driver pmi_of_platform_driver = {
+	.name		= "pmi",
+	.match_table	= pmi_match,
+	.probe		= pmi_of_probe,
+	.remove		= pmi_of_remove
+};
+
+static int __init pmi_module_init(void)
+{
+	return of_register_platform_driver(&pmi_of_platform_driver);
+}
+module_init(pmi_module_init);
+
+static void __exit pmi_module_exit(void)
+{
+	of_unregister_platform_driver(&pmi_of_platform_driver);
+}
+module_exit(pmi_module_exit);
+
+void pmi_send_message(struct of_device *device, pmi_message_t msg)
+{
+	struct pmi_data *data;
+	unsigned long flags;
+	DECLARE_COMPLETION_ONSTACK(completion);
+
+	data = device->dev.driver_data;
+
+	mutex_lock(&data->msg_mutex);
+
+	data->msg = msg;
+	pr_debug("pmi_send_message: msg is %08x\n", *(u32*)&msg);
+
+	data->completion = &completion;
+
+	spin_lock_irqsave(&data->pmi_spinlock, flags);
+	iowrite8(msg.data0, data->pmi_reg + PMI_WRITE_DATA0);
+	iowrite8(msg.data1, data->pmi_reg + PMI_WRITE_DATA1);
+	iowrite8(msg.data2, data->pmi_reg + PMI_WRITE_DATA2);
+	iowrite8(msg.type, data->pmi_reg + PMI_WRITE_TYPE);
+	spin_unlock_irqrestore(&data->pmi_spinlock, flags);
+
+	pr_debug("pmi_send_message: wait for completion\n");
+
+	wait_for_completion_interruptible_timeout(data->completion,
+						  PMI_TIMEOUT);
+
+	data->completion = NULL;
+
+	mutex_unlock(&data->msg_mutex);
+}
+EXPORT_SYMBOL_GPL(pmi_send_message);
+
+void pmi_register_handler(struct of_device *device,
+			  struct pmi_handler *handler)
+{
+	struct pmi_data *data;
+	data = device->dev.driver_data;
+
+	spin_lock(&data->handler_spinlock);
+	list_add_tail(&handler->node, &data->handler);
+	spin_unlock(&data->handler_spinlock);
+}
+EXPORT_SYMBOL_GPL(pmi_register_handler);
+
+void pmi_unregister_handler(struct of_device *device,
+			    struct pmi_handler *handler)
+{
+	struct pmi_data *data;
+
+	pr_debug("pmi: unregistering handler %p\n", handler);
+
+	data = device->dev.driver_data;
+
+	spin_lock(&data->handler_spinlock);
+	list_del(&handler->node);
+	spin_unlock(&data->handler_spinlock);
+}
+EXPORT_SYMBOL_GPL(pmi_unregister_handler);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
+MODULE_DESCRIPTION("IBM Platform Management Interrupt driver");
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
index e657559..a457ac1 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
@@ -1,13 +1,12 @@
 /*
- * arch/powerpc/sysdev/qe_lib/ucc_fast.c
- *
- * QE UCC Fast API Set - UCC Fast specific routines implementations.
- *
  * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
  *
  * Authors: 	Shlomi Gridish <gridish@freescale.com>
  * 		Li Yang <leoli@freescale.com>
  *
+ * Description:
+ * QE UCC Fast API Set - UCC Fast specific routines implementations.
+ *
  * 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
@@ -27,79 +26,61 @@
 #include <asm/ucc.h>
 #include <asm/ucc_fast.h>
 
-#define uccf_printk(level, format, arg...) \
-	printk(level format "\n", ## arg)
-
-#define uccf_dbg(format, arg...) \
-	uccf_printk(KERN_DEBUG , format , ## arg)
-#define uccf_err(format, arg...) \
-	uccf_printk(KERN_ERR , format , ## arg)
-#define uccf_info(format, arg...) \
-	uccf_printk(KERN_INFO , format , ## arg)
-#define uccf_warn(format, arg...) \
-	uccf_printk(KERN_WARNING , format , ## arg)
-
-#ifdef UCCF_VERBOSE_DEBUG
-#define uccf_vdbg uccf_dbg
-#else
-#define uccf_vdbg(fmt, args...) do { } while (0)
-#endif				/* UCCF_VERBOSE_DEBUG */
-
 void ucc_fast_dump_regs(struct ucc_fast_private * uccf)
 {
-	uccf_info("UCC%d Fast registers:", uccf->uf_info->ucc_num);
-	uccf_info("Base address: 0x%08x", (u32) uccf->uf_regs);
+	printk(KERN_INFO "UCC%d Fast registers:", uccf->uf_info->ucc_num);
+	printk(KERN_INFO "Base address: 0x%08x", (u32) uccf->uf_regs);
 
-	uccf_info("gumr  : addr - 0x%08x, val - 0x%08x",
+	printk(KERN_INFO "gumr  : addr - 0x%08x, val - 0x%08x",
 		  (u32) & uccf->uf_regs->gumr, in_be32(&uccf->uf_regs->gumr));
-	uccf_info("upsmr : addr - 0x%08x, val - 0x%08x",
+	printk(KERN_INFO "upsmr : addr - 0x%08x, val - 0x%08x",
 		  (u32) & uccf->uf_regs->upsmr, in_be32(&uccf->uf_regs->upsmr));
-	uccf_info("utodr : addr - 0x%08x, val - 0x%04x",
+	printk(KERN_INFO "utodr : addr - 0x%08x, val - 0x%04x",
 		  (u32) & uccf->uf_regs->utodr, in_be16(&uccf->uf_regs->utodr));
-	uccf_info("udsr  : addr - 0x%08x, val - 0x%04x",
+	printk(KERN_INFO "udsr  : addr - 0x%08x, val - 0x%04x",
 		  (u32) & uccf->uf_regs->udsr, in_be16(&uccf->uf_regs->udsr));
-	uccf_info("ucce  : addr - 0x%08x, val - 0x%08x",
+	printk(KERN_INFO "ucce  : addr - 0x%08x, val - 0x%08x",
 		  (u32) & uccf->uf_regs->ucce, in_be32(&uccf->uf_regs->ucce));
-	uccf_info("uccm  : addr - 0x%08x, val - 0x%08x",
+	printk(KERN_INFO "uccm  : addr - 0x%08x, val - 0x%08x",
 		  (u32) & uccf->uf_regs->uccm, in_be32(&uccf->uf_regs->uccm));
-	uccf_info("uccs  : addr - 0x%08x, val - 0x%02x",
+	printk(KERN_INFO "uccs  : addr - 0x%08x, val - 0x%02x",
 		  (u32) & uccf->uf_regs->uccs, uccf->uf_regs->uccs);
-	uccf_info("urfb  : addr - 0x%08x, val - 0x%08x",
+	printk(KERN_INFO "urfb  : addr - 0x%08x, val - 0x%08x",
 		  (u32) & uccf->uf_regs->urfb, in_be32(&uccf->uf_regs->urfb));
-	uccf_info("urfs  : addr - 0x%08x, val - 0x%04x",
+	printk(KERN_INFO "urfs  : addr - 0x%08x, val - 0x%04x",
 		  (u32) & uccf->uf_regs->urfs, in_be16(&uccf->uf_regs->urfs));
-	uccf_info("urfet : addr - 0x%08x, val - 0x%04x",
+	printk(KERN_INFO "urfet : addr - 0x%08x, val - 0x%04x",
 		  (u32) & uccf->uf_regs->urfet, in_be16(&uccf->uf_regs->urfet));
-	uccf_info("urfset: addr - 0x%08x, val - 0x%04x",
+	printk(KERN_INFO "urfset: addr - 0x%08x, val - 0x%04x",
 		  (u32) & uccf->uf_regs->urfset,
 		  in_be16(&uccf->uf_regs->urfset));
-	uccf_info("utfb  : addr - 0x%08x, val - 0x%08x",
+	printk(KERN_INFO "utfb  : addr - 0x%08x, val - 0x%08x",
 		  (u32) & uccf->uf_regs->utfb, in_be32(&uccf->uf_regs->utfb));
-	uccf_info("utfs  : addr - 0x%08x, val - 0x%04x",
+	printk(KERN_INFO "utfs  : addr - 0x%08x, val - 0x%04x",
 		  (u32) & uccf->uf_regs->utfs, in_be16(&uccf->uf_regs->utfs));
-	uccf_info("utfet : addr - 0x%08x, val - 0x%04x",
+	printk(KERN_INFO "utfet : addr - 0x%08x, val - 0x%04x",
 		  (u32) & uccf->uf_regs->utfet, in_be16(&uccf->uf_regs->utfet));
-	uccf_info("utftt : addr - 0x%08x, val - 0x%04x",
+	printk(KERN_INFO "utftt : addr - 0x%08x, val - 0x%04x",
 		  (u32) & uccf->uf_regs->utftt, in_be16(&uccf->uf_regs->utftt));
-	uccf_info("utpt  : addr - 0x%08x, val - 0x%04x",
+	printk(KERN_INFO "utpt  : addr - 0x%08x, val - 0x%04x",
 		  (u32) & uccf->uf_regs->utpt, in_be16(&uccf->uf_regs->utpt));
-	uccf_info("urtry : addr - 0x%08x, val - 0x%08x",
+	printk(KERN_INFO "urtry : addr - 0x%08x, val - 0x%08x",
 		  (u32) & uccf->uf_regs->urtry, in_be32(&uccf->uf_regs->urtry));
-	uccf_info("guemr : addr - 0x%08x, val - 0x%02x",
+	printk(KERN_INFO "guemr : addr - 0x%08x, val - 0x%02x",
 		  (u32) & uccf->uf_regs->guemr, uccf->uf_regs->guemr);
 }
 
 u32 ucc_fast_get_qe_cr_subblock(int uccf_num)
 {
 	switch (uccf_num) {
-	case 0:	return QE_CR_SUBBLOCK_UCCFAST1;
+	case 0: return QE_CR_SUBBLOCK_UCCFAST1;
 	case 1: return QE_CR_SUBBLOCK_UCCFAST2;
 	case 2: return QE_CR_SUBBLOCK_UCCFAST3;
 	case 3: return QE_CR_SUBBLOCK_UCCFAST4;
 	case 4: return QE_CR_SUBBLOCK_UCCFAST5;
 	case 5: return QE_CR_SUBBLOCK_UCCFAST6;
 	case 6: return QE_CR_SUBBLOCK_UCCFAST7;
-	case 7:	return QE_CR_SUBBLOCK_UCCFAST8;
+	case 7: return QE_CR_SUBBLOCK_UCCFAST8;
 	default: return QE_CR_SUBBLOCK_INVALID;
 	}
 }
@@ -153,84 +134,72 @@
 {
 	struct ucc_fast_private *uccf;
 	struct ucc_fast *uf_regs;
-	u32 gumr = 0;
+	u32 gumr;
 	int ret;
 
-	uccf_vdbg("%s: IN", __FUNCTION__);
-
 	if (!uf_info)
 		return -EINVAL;
 
 	/* check if the UCC port number is in range. */
 	if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) {
-		uccf_err("ucc_fast_init: Illegal UCC number!");
+		printk(KERN_ERR "%s: illegal UCC number", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	/* Check that 'max_rx_buf_length' is properly aligned (4). */
 	if (uf_info->max_rx_buf_length & (UCC_FAST_MRBLR_ALIGNMENT - 1)) {
-		uccf_err("ucc_fast_init: max_rx_buf_length not aligned.");
+		printk(KERN_ERR "%s: max_rx_buf_length not aligned", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	/* Validate Virtual Fifo register values */
 	if (uf_info->urfs < UCC_FAST_URFS_MIN_VAL) {
-		uccf_err
-		    ("ucc_fast_init: Virtual Fifo register urfs too small.");
+		printk(KERN_ERR "%s: urfs is too small", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	if (uf_info->urfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
-		uccf_err
-		    ("ucc_fast_init: Virtual Fifo register urfs not aligned.");
+		printk(KERN_ERR "%s: urfs is not aligned", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	if (uf_info->urfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
-		uccf_err
-		    ("ucc_fast_init: Virtual Fifo register urfet not aligned.");
+		printk(KERN_ERR "%s: urfet is not aligned.", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	if (uf_info->urfset & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
-		uccf_err
-		   ("ucc_fast_init: Virtual Fifo register urfset not aligned.");
+		printk(KERN_ERR "%s: urfset is not aligned", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	if (uf_info->utfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
-		uccf_err
-		    ("ucc_fast_init: Virtual Fifo register utfs not aligned.");
+		printk(KERN_ERR "%s: utfs is not aligned", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	if (uf_info->utfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
-		uccf_err
-		    ("ucc_fast_init: Virtual Fifo register utfet not aligned.");
+		printk(KERN_ERR "%s: utfet is not aligned", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	if (uf_info->utftt & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
-		uccf_err
-		    ("ucc_fast_init: Virtual Fifo register utftt not aligned.");
+		printk(KERN_ERR "%s: utftt is not aligned", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	uccf = kzalloc(sizeof(struct ucc_fast_private), GFP_KERNEL);
 	if (!uccf) {
-		uccf_err
-		    ("ucc_fast_init: No memory for UCC slow data structure!");
+		printk(KERN_ERR "%s: Cannot allocate private data", __FUNCTION__);
 		return -ENOMEM;
 	}
 
 	/* Fill fast UCC structure */
 	uccf->uf_info = uf_info;
 	/* Set the PHY base address */
-	uccf->uf_regs =
-	    (struct ucc_fast *) ioremap(uf_info->regs, sizeof(struct ucc_fast));
+	uccf->uf_regs = ioremap(uf_info->regs, sizeof(struct ucc_fast));
 	if (uccf->uf_regs == NULL) {
-		uccf_err
-		    ("ucc_fast_init: No memory map for UCC slow controller!");
+		printk(KERN_ERR "%s: Cannot map UCC registers", __FUNCTION__);
 		return -ENOMEM;
 	}
 
@@ -249,7 +218,7 @@
 
 	/* Init Guemr register */
 	if ((ret = ucc_init_guemr((struct ucc_common *) (uf_regs)))) {
-		uccf_err("ucc_fast_init: Could not init the guemr register.");
+		printk(KERN_ERR "%s: cannot init GUEMR", __FUNCTION__);
 		ucc_fast_free(uccf);
 		return ret;
 	}
@@ -258,7 +227,7 @@
 	if ((ret = ucc_set_type(uf_info->ucc_num,
 				(struct ucc_common *) (uf_regs),
 				UCC_SPEED_TYPE_FAST))) {
-		uccf_err("ucc_fast_init: Could not set type to fast.");
+		printk(KERN_ERR "%s: cannot set UCC type", __FUNCTION__);
 		ucc_fast_free(uccf);
 		return ret;
 	}
@@ -267,10 +236,9 @@
 
 	/* Set GUMR */
 	/* For more details see the hardware spec. */
-	/* gumr starts as zero. */
+	gumr = uf_info->ttx_trx;
 	if (uf_info->tci)
 		gumr |= UCC_FAST_GUMR_TCI;
-	gumr |= uf_info->ttx_trx;
 	if (uf_info->cdp)
 		gumr |= UCC_FAST_GUMR_CDP;
 	if (uf_info->ctsp)
@@ -298,9 +266,7 @@
 	uccf->ucc_fast_tx_virtual_fifo_base_offset =
 	    qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
 	if (IS_MURAM_ERR(uccf->ucc_fast_tx_virtual_fifo_base_offset)) {
-		uccf_err
-		    ("ucc_fast_init: Can not allocate MURAM memory for "
-			"struct ucc_fastx_virtual_fifo_base_offset.");
+		printk(KERN_ERR "%s: cannot allocate MURAM for TX FIFO", __FUNCTION__);
 		uccf->ucc_fast_tx_virtual_fifo_base_offset = 0;
 		ucc_fast_free(uccf);
 		return -ENOMEM;
@@ -308,14 +274,11 @@
 
 	/* Allocate memory for Rx Virtual Fifo */
 	uccf->ucc_fast_rx_virtual_fifo_base_offset =
-	    qe_muram_alloc(uf_info->urfs +
-			   (u32)
+		qe_muram_alloc(uf_info->urfs +
 			   UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR,
 			   UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
 	if (IS_MURAM_ERR(uccf->ucc_fast_rx_virtual_fifo_base_offset)) {
-		uccf_err
-		    ("ucc_fast_init: Can not allocate MURAM memory for "
-			"ucc_fast_rx_virtual_fifo_base_offset.");
+		printk(KERN_ERR "%s: cannot allocate MURAM for RX FIFO", __FUNCTION__);
 		uccf->ucc_fast_rx_virtual_fifo_base_offset = 0;
 		ucc_fast_free(uccf);
 		return -ENOMEM;
@@ -342,26 +305,22 @@
 	/* If NMSI (not Tsa), set Tx and Rx clock. */
 	if (!uf_info->tsa) {
 		/* Rx clock routing */
-		if (uf_info->rx_clock != QE_CLK_NONE) {
-			if (ucc_set_qe_mux_rxtx
-			    (uf_info->ucc_num, uf_info->rx_clock,
-			     COMM_DIR_RX)) {
-				uccf_err
-		("ucc_fast_init: Illegal value for parameter 'RxClock'.");
-				ucc_fast_free(uccf);
-				return -EINVAL;
-			}
+		if ((uf_info->rx_clock != QE_CLK_NONE) &&
+		    ucc_set_qe_mux_rxtx(uf_info->ucc_num, uf_info->rx_clock,
+					COMM_DIR_RX)) {
+			printk(KERN_ERR "%s: illegal value for RX clock",
+			       __FUNCTION__);
+			ucc_fast_free(uccf);
+			return -EINVAL;
 		}
 		/* Tx clock routing */
-		if (uf_info->tx_clock != QE_CLK_NONE) {
-			if (ucc_set_qe_mux_rxtx
-			    (uf_info->ucc_num, uf_info->tx_clock,
-			     COMM_DIR_TX)) {
-				uccf_err
-		("ucc_fast_init: Illegal value for parameter 'TxClock'.");
-				ucc_fast_free(uccf);
-				return -EINVAL;
-			}
+		if ((uf_info->tx_clock != QE_CLK_NONE) &&
+		    ucc_set_qe_mux_rxtx(uf_info->ucc_num, uf_info->tx_clock,
+					COMM_DIR_TX)) {
+			printk(KERN_ERR "%s: illegal value for TX clock",
+			       __FUNCTION__);
+			ucc_fast_free(uccf);
+			return -EINVAL;
 		}
 	}
 
@@ -370,9 +329,9 @@
 
 	/* First, clear anything pending at UCC level,
 	 * otherwise, old garbage may come through
-	 * as soon as the dam is opened
-	 * Writing '1' clears
-	 */
+	 * as soon as the dam is opened. */
+
+	/* Writing '1' clears */
 	out_be32(&uf_regs->ucce, 0xffffffff);
 
 	*uccf_ret = uccf;
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
index 0e97e5c..817df73 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
@@ -19,7 +19,6 @@
 #include <linux/stddef.h>
 #include <linux/interrupt.h>
 
-#include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/immap_qe.h>
 #include <asm/qe.h>
@@ -27,24 +26,6 @@
 #include <asm/ucc.h>
 #include <asm/ucc_slow.h>
 
-#define uccs_printk(level, format, arg...) \
-        printk(level format "\n", ## arg)
-
-#define uccs_dbg(format, arg...) \
-	uccs_printk(KERN_DEBUG , format , ## arg)
-#define uccs_err(format, arg...) \
-	uccs_printk(KERN_ERR , format , ## arg)
-#define uccs_info(format, arg...) \
-	uccs_printk(KERN_INFO , format , ## arg)
-#define uccs_warn(format, arg...) \
-	uccs_printk(KERN_WARNING , format , ## arg)
-
-#ifdef UCCS_VERBOSE_DEBUG
-#define uccs_vdbg uccs_dbg
-#else
-#define uccs_vdbg(fmt, args...) do { } while (0)
-#endif				/* UCCS_VERBOSE_DEBUG */
-
 u32 ucc_slow_get_qe_cr_subblock(int uccs_num)
 {
 	switch (uccs_num) {
@@ -135,51 +116,53 @@
 
 int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret)
 {
+	struct ucc_slow_private *uccs;
 	u32 i;
 	struct ucc_slow *us_regs;
 	u32 gumr;
-	u8 function_code = 0;
-	u8 *bd;
-	struct ucc_slow_private *uccs;
+	struct qe_bd *bd;
 	u32 id;
 	u32 command;
-	int ret;
-
-	uccs_vdbg("%s: IN", __FUNCTION__);
+	int ret = 0;
 
 	if (!us_info)
 		return -EINVAL;
 
 	/* check if the UCC port number is in range. */
 	if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) {
-		uccs_err("ucc_slow_init: Illegal UCC number!");
+		printk(KERN_ERR "%s: illegal UCC number", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	/*
 	 * Set mrblr
 	 * Check that 'max_rx_buf_length' is properly aligned (4), unless
- 	 * rfw is 1, meaning that QE accepts one byte at a time, unlike normal
+	 * rfw is 1, meaning that QE accepts one byte at a time, unlike normal
 	 * case when QE accepts 32 bits at a time.
 	 */
 	if ((!us_info->rfw) &&
 		(us_info->max_rx_buf_length & (UCC_SLOW_MRBLR_ALIGNMENT - 1))) {
-		uccs_err("max_rx_buf_length not aligned.");
+		printk(KERN_ERR "max_rx_buf_length not aligned.");
 		return -EINVAL;
 	}
 
 	uccs = kzalloc(sizeof(struct ucc_slow_private), GFP_KERNEL);
 	if (!uccs) {
-		uccs_err
-		    ("ucc_slow_init: No memory for UCC slow data structure!");
+		printk(KERN_ERR "%s: Cannot allocate private data", __FUNCTION__);
 		return -ENOMEM;
 	}
 
 	/* Fill slow UCC structure */
 	uccs->us_info = us_info;
+	/* Set the PHY base address */
+	uccs->us_regs = ioremap(us_info->regs, sizeof(struct ucc_slow));
+	if (uccs->us_regs == NULL) {
+		printk(KERN_ERR "%s: Cannot map UCC registers", __FUNCTION__);
+		return -ENOMEM;
+	}
+
 	uccs->saved_uccm = 0;
 	uccs->p_rx_frame = 0;
-	uccs->us_regs = us_info->regs;
 	us_regs = uccs->us_regs;
 	uccs->p_ucce = (u16 *) & (us_regs->ucce);
 	uccs->p_uccm = (u16 *) & (us_regs->uccm);
@@ -190,24 +173,22 @@
 #endif				/* STATISTICS */
 
 	/* Get PRAM base */
-	uccs->us_pram_offset = qe_muram_alloc(UCC_SLOW_PRAM_SIZE,
-						 ALIGNMENT_OF_UCC_SLOW_PRAM);
+	uccs->us_pram_offset =
+		qe_muram_alloc(UCC_SLOW_PRAM_SIZE, ALIGNMENT_OF_UCC_SLOW_PRAM);
 	if (IS_MURAM_ERR(uccs->us_pram_offset)) {
-		uccs_err
-		    ("ucc_slow_init: Can not allocate MURAM memory "
-			"for Slow UCC.");
+		printk(KERN_ERR "%s: cannot allocate MURAM for PRAM", __FUNCTION__);
 		ucc_slow_free(uccs);
 		return -ENOMEM;
 	}
 	id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
 	qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, id, QE_CR_PROTOCOL_UNSPECIFIED,
-			(u32) uccs->us_pram_offset);
+		     uccs->us_pram_offset);
 
 	uccs->us_pram = qe_muram_addr(uccs->us_pram_offset);
 
 	/* Init Guemr register */
 	if ((ret = ucc_init_guemr((struct ucc_common *) (us_info->regs)))) {
-		uccs_err("ucc_slow_init: Could not init the guemr register.");
+		printk(KERN_ERR "%s: cannot init GUEMR", __FUNCTION__);
 		ucc_slow_free(uccs);
 		return ret;
 	}
@@ -216,7 +197,7 @@
 	if ((ret = ucc_set_type(us_info->ucc_num,
 				(struct ucc_common *) (us_info->regs),
 				UCC_SPEED_TYPE_SLOW))) {
-		uccs_err("ucc_slow_init: Could not init the guemr register.");
+		printk(KERN_ERR "%s: cannot set UCC type", __FUNCTION__);
 		ucc_slow_free(uccs);
 		return ret;
 	}
@@ -230,7 +211,7 @@
 		qe_muram_alloc(us_info->rx_bd_ring_len * sizeof(struct qe_bd),
 				QE_ALIGNMENT_OF_BD);
 	if (IS_MURAM_ERR(uccs->rx_base_offset)) {
-		uccs_err("ucc_slow_init: No memory for Rx BD's.");
+		printk(KERN_ERR "%s: cannot allocate RX BDs", __FUNCTION__);
 		uccs->rx_base_offset = 0;
 		ucc_slow_free(uccs);
 		return -ENOMEM;
@@ -240,7 +221,7 @@
 		qe_muram_alloc(us_info->tx_bd_ring_len * sizeof(struct qe_bd),
 			QE_ALIGNMENT_OF_BD);
 	if (IS_MURAM_ERR(uccs->tx_base_offset)) {
-		uccs_err("ucc_slow_init: No memory for Tx BD's.");
+		printk(KERN_ERR "%s: cannot allocate TX BDs", __FUNCTION__);
 		uccs->tx_base_offset = 0;
 		ucc_slow_free(uccs);
 		return -ENOMEM;
@@ -248,34 +229,33 @@
 
 	/* Init Tx bds */
 	bd = uccs->confBd = uccs->tx_bd = qe_muram_addr(uccs->tx_base_offset);
-	for (i = 0; i < us_info->tx_bd_ring_len; i++) {
+	for (i = 0; i < us_info->tx_bd_ring_len - 1; i++) {
 		/* clear bd buffer */
-		out_be32(&(((struct qe_bd *)bd)->buf), 0);
+		out_be32(&bd->buf, 0);
 		/* set bd status and length */
-		out_be32((u32*)bd, 0);
-		bd += sizeof(struct qe_bd);
+		out_be32((u32 *) bd, 0);
+		bd++;
 	}
-	bd -= sizeof(struct qe_bd);
-	/* set bd status and length */
-	out_be32((u32*)bd, T_W);	/* for last BD set Wrap bit */
+	/* for last BD set Wrap bit */
+	out_be32(&bd->buf, 0);
+	out_be32((u32 *) bd, cpu_to_be32(T_W));
 
 	/* Init Rx bds */
 	bd = uccs->rx_bd = qe_muram_addr(uccs->rx_base_offset);
-	for (i = 0; i < us_info->rx_bd_ring_len; i++) {
+	for (i = 0; i < us_info->rx_bd_ring_len - 1; i++) {
 		/* set bd status and length */
 		out_be32((u32*)bd, 0);
 		/* clear bd buffer */
-		out_be32(&(((struct qe_bd *)bd)->buf), 0);
-		bd += sizeof(struct qe_bd);
+		out_be32(&bd->buf, 0);
+		bd++;
 	}
-	bd -= sizeof(struct qe_bd);
-	/* set bd status and length */
-	out_be32((u32*)bd, R_W);	/* for last BD set Wrap bit */
+	/* for last BD set Wrap bit */
+	out_be32((u32*)bd, cpu_to_be32(R_W));
+	out_be32(&bd->buf, 0);
 
 	/* Set GUMR (For more details see the hardware spec.). */
 	/* gumr_h */
-	gumr = 0;
-	gumr |= us_info->tcrc;
+	gumr = us_info->tcrc;
 	if (us_info->cdp)
 		gumr |= UCC_SLOW_GUMR_H_CDP;
 	if (us_info->ctsp)
@@ -295,7 +275,8 @@
 	out_be32(&us_regs->gumr_h, gumr);
 
 	/* gumr_l */
-	gumr = 0;
+	gumr = us_info->tdcr | us_info->rdcr | us_info->tenc | us_info->renc |
+		us_info->diag | us_info->mode;
 	if (us_info->tci)
 		gumr |= UCC_SLOW_GUMR_L_TCI;
 	if (us_info->rinv)
@@ -304,23 +285,14 @@
 		gumr |= UCC_SLOW_GUMR_L_TINV;
 	if (us_info->tend)
 		gumr |= UCC_SLOW_GUMR_L_TEND;
-	gumr |= us_info->tdcr;
-	gumr |= us_info->rdcr;
-	gumr |= us_info->tenc;
-	gumr |= us_info->renc;
-	gumr |= us_info->diag;
-	gumr |= us_info->mode;
 	out_be32(&us_regs->gumr_l, gumr);
 
 	/* Function code registers */
-	/* function_code has initial value 0 */
 
 	/* if the data is in cachable memory, the 'global' */
 	/* in the function code should be set. */
-	function_code |= us_info->data_mem_part;
-	function_code |= QE_BMR_BYTE_ORDER_BO_MOT;	/* Required for QE */
-	uccs->us_pram->tfcr = function_code;
-	uccs->us_pram->rfcr = function_code;
+	uccs->us_pram->tfcr = uccs->us_pram->rfcr =
+		us_info->data_mem_part | QE_BMR_BYTE_ORDER_BO_MOT;
 
 	/* rbase, tbase are offsets from MURAM base */
 	out_be16(&uccs->us_pram->rbase, uccs->us_pram_offset);
@@ -336,34 +308,29 @@
 	/* If NMSI (not Tsa), set Tx and Rx clock. */
 	if (!us_info->tsa) {
 		/* Rx clock routing */
-		if (ucc_set_qe_mux_rxtx
-		    (us_info->ucc_num, us_info->rx_clock, COMM_DIR_RX)) {
-			uccs_err
-			    ("ucc_slow_init: Illegal value for parameter"
-				" 'RxClock'.");
+		if (ucc_set_qe_mux_rxtx(us_info->ucc_num, us_info->rx_clock,
+					COMM_DIR_RX)) {
+			printk(KERN_ERR "%s: illegal value for RX clock",
+			       __FUNCTION__);
 			ucc_slow_free(uccs);
 			return -EINVAL;
 		}
 		/* Tx clock routing */
-		if (ucc_set_qe_mux_rxtx(us_info->ucc_num,
-				 us_info->tx_clock, COMM_DIR_TX)) {
-			uccs_err
-			    ("ucc_slow_init: Illegal value for parameter "
-				"'TxClock'.");
+		if (ucc_set_qe_mux_rxtx(us_info->ucc_num, us_info->tx_clock,
+					COMM_DIR_TX)) {
+			printk(KERN_ERR "%s: illegal value for TX clock",
+			       __FUNCTION__);
 			ucc_slow_free(uccs);
 			return -EINVAL;
 		}
 	}
 
-	/*
-	 * INTERRUPTS
-	 */
 	/* Set interrupt mask register at UCC level. */
 	out_be16(&us_regs->uccm, us_info->uccm_mask);
 
-	/* First, clear anything pending at UCC level, */
-	/* otherwise, old garbage may come through */
-	/* as soon as the dam is opened. */
+	/* First, clear anything pending at UCC level,
+	 * otherwise, old garbage may come through
+	 * as soon as the dam is opened. */
 
 	/* Writing '1' clears */
 	out_be16(&us_regs->ucce, 0xffff);
@@ -400,3 +367,5 @@
 
 	kfree(uccs);
 }
+
+
diff --git a/arch/sh/kernel/cpu/sh2/clock-sh7619.c b/arch/sh/kernel/cpu/sh2/clock-sh7619.c
index d0440b2..d2c1579 100644
--- a/arch/sh/kernel/cpu/sh2/clock-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/clock-sh7619.c
@@ -18,8 +18,8 @@
 #include <asm/freq.h>
 #include <asm/io.h>
 
-const static int pll1rate[]={1,2};
-const static int pfc_divisors[]={1,2,0,4};
+static const int pll1rate[] = {1,2};
+static const int pfc_divisors[] = {1,2,0,4};
 
 #if (CONFIG_SH_CLK_MD == 1) || (CONFIG_SH_CLK_MD == 2)
 #define PLL2 (4)
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
index a9ad309..82d7f99 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
@@ -18,8 +18,8 @@
 #include <asm/freq.h>
 #include <asm/io.h>
 
-const static int pll1rate[]={1,2,3,4,6,8};
-const static int pfc_divisors[]={1,2,3,4,6,8,12};
+static const int pll1rate[]={1,2,3,4,6,8};
+static const int pfc_divisors[]={1,2,3,4,6,8,12};
 #define ifc_divisors pfc_divisors
 
 #if (CONFIG_SH_CLK_MD == 2)
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
index dbfab8f..50ccc7f 100644
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -217,7 +217,7 @@
    # Some platforms pre-zero memory, in which case the kernel doesn't need to
    config ZERO_BSS
    	  bool
-	  depends !V850E2_SIM85E2C
+	  depends on !V850E2_SIM85E2C
 	  default y
 
    # The crappy-ass zone allocator requires that the start of allocatable
diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c
index bd30d13..8047ea8 100644
--- a/arch/x86_64/kernel/early-quirks.c
+++ b/arch/x86_64/kernel/early-quirks.c
@@ -53,7 +53,9 @@
 		return;
 
 	nvidia_hpet_detected = 0;
-	acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check);
+	if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check))
+		return;
+
 	if (nvidia_hpet_detected == 0) {
 		acpi_skip_timer_override = 1;
 		printk(KERN_INFO "Nvidia board "
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index a87c517..c9addcf 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -418,7 +418,7 @@
 	set_kset_name("timer"),
 };
 
-/* XXX this driverfs stuff should probably go elsewhere later -john */
+/* XXX this sysfs stuff should probably go elsewhere later -john */
 static struct sys_device device_timer = {
 	.id	= 0,
 	.cls	= &timer_sysclass,
diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched
index 903f0d3..7e803fc 100644
--- a/block/Kconfig.iosched
+++ b/block/Kconfig.iosched
@@ -16,10 +16,10 @@
 	tristate "Anticipatory I/O scheduler"
 	default y
 	---help---
-	  The anticipatory I/O scheduler is the default disk scheduler. It is
-	  generally a good choice for most environments, but is quite large and
-	  complex when compared to the deadline I/O scheduler, it can also be
-	  slower in some cases especially some database loads.
+	  The anticipatory I/O scheduler is generally a good choice for most
+	  environments, but is quite large and complex when compared to the
+	  deadline I/O scheduler, it can also be slower in some cases
+	  especially some database loads.
 
 config IOSCHED_DEADLINE
 	tristate "Deadline I/O scheduler"
@@ -38,6 +38,7 @@
 	  The CFQ I/O scheduler tries to distribute bandwidth equally
 	  among all processes in the system. It should provide a fair
 	  working environment, suitable for desktop systems.
+	  This is the default I/O scheduler.
 
 choice
 	prompt "Default I/O scheduler"
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 20eacc2..e942ffe 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -13,6 +13,7 @@
 	depends on IA64 || X86
 	depends on PCI
 	depends on PM
+	select PNP
 	default y
 	---help---
 	  Advanced Configuration and Power Interface (ACPI) support for 
@@ -132,15 +133,6 @@
 	  Note that this is an ref. implementation only.  It may or may not work
 	  for your integrated video device.
 
-config ACPI_HOTKEY
-	tristate "Generic Hotkey (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
-	depends on X86
-	default n
-	help
-	  Experimental consolidated hotkey driver.
-	  If you are unsure, say N.
-
 config ACPI_FAN
 	tristate "Fan"
 	default y
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 856c32b..5956e9f 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -46,7 +46,6 @@
 obj-$(CONFIG_ACPI_DOCK)		+= dock.o
 obj-$(CONFIG_ACPI_BAY)		+= bay.o
 obj-$(CONFIG_ACPI_VIDEO)	+= video.o
-obj-$(CONFIG_ACPI_HOTKEY)	+= hotkey.o
 obj-y				+= pci_root.o pci_link.o pci_irq.o pci_bind.o
 obj-$(CONFIG_ACPI_POWER)	+= power.o
 obj-$(CONFIG_ACPI_PROCESSOR)	+= processor.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 6daeace..37c7dc4 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -35,7 +35,6 @@
 #define ACPI_AC_COMPONENT		0x00020000
 #define ACPI_AC_CLASS			"ac_adapter"
 #define ACPI_AC_HID 			"ACPI0003"
-#define ACPI_AC_DRIVER_NAME		"ACPI AC Adapter Driver"
 #define ACPI_AC_DEVICE_NAME		"AC Adapter"
 #define ACPI_AC_FILE_STATE		"state"
 #define ACPI_AC_NOTIFY_STATUS		0x80
@@ -44,10 +43,10 @@
 #define ACPI_AC_STATUS_UNKNOWN		0xFF
 
 #define _COMPONENT		ACPI_AC_COMPONENT
-ACPI_MODULE_NAME("acpi_ac")
+ACPI_MODULE_NAME("ac");
 
-    MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME);
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION("ACPI AC Adapter Driver");
 MODULE_LICENSE("GPL");
 
 extern struct proc_dir_entry *acpi_lock_ac_dir(void);
@@ -58,7 +57,7 @@
 static int acpi_ac_open_fs(struct inode *inode, struct file *file);
 
 static struct acpi_driver acpi_ac_driver = {
-	.name = ACPI_AC_DRIVER_NAME,
+	.name = "ac",
 	.class = ACPI_AC_CLASS,
 	.ids = ACPI_AC_HID,
 	.ops = {
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index cd946ed..c261726 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -35,14 +35,13 @@
 #define ACPI_MEMORY_DEVICE_COMPONENT		0x08000000UL
 #define ACPI_MEMORY_DEVICE_CLASS		"memory"
 #define ACPI_MEMORY_DEVICE_HID			"PNP0C80"
-#define ACPI_MEMORY_DEVICE_DRIVER_NAME		"Hotplug Mem Driver"
 #define ACPI_MEMORY_DEVICE_NAME			"Hotplug Mem Device"
 
 #define _COMPONENT		ACPI_MEMORY_DEVICE_COMPONENT
 
-ACPI_MODULE_NAME("acpi_memory")
-    MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>");
-MODULE_DESCRIPTION(ACPI_MEMORY_DEVICE_DRIVER_NAME);
+ACPI_MODULE_NAME("acpi_memhotplug");
+MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>");
+MODULE_DESCRIPTION("Hotplug Mem Driver");
 MODULE_LICENSE("GPL");
 
 /* ACPI _STA method values */
@@ -60,7 +59,7 @@
 static int acpi_memory_device_start(struct acpi_device *device);
 
 static struct acpi_driver acpi_memory_device_driver = {
-	.name = ACPI_MEMORY_DEVICE_DRIVER_NAME,
+	.name = "acpi_memhotplug",
 	.class = ACPI_MEMORY_DEVICE_CLASS,
 	.ids = ACPI_MEMORY_DEVICE_HID,
 	.ops = {
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index 31ad70a..772299f 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -141,6 +141,7 @@
 		W5A,		//W5A
 		W3V,            //W3030V
 		xxN,		//M2400N, M3700N, M5200N, M6800N, S1300N, S5200N
+		A4S,            //Z81sp
 		//(Centrino)
 		END_MODEL
 	} model;		//Models currently supported
@@ -397,7 +398,16 @@
 	 .brightness_set = "SPLV",
 	 .brightness_get = "GPLV",
 	 .display_set = "SDSP",
-	 .display_get = "\\ADVG"}
+	.display_get = "\\ADVG"},
+
+	{
+		.name              = "A4S",
+		.brightness_set    = "SPLV",
+		.brightness_get    = "GPLV",
+		.mt_bt_switch      = "BLED",
+		.mt_wled           = "WLED"
+	}
+
 };
 
 /* procdir we use */
@@ -421,7 +431,7 @@
 static int asus_hotk_add(struct acpi_device *device);
 static int asus_hotk_remove(struct acpi_device *device, int type);
 static struct acpi_driver asus_hotk_driver = {
-	.name = ACPI_HOTK_NAME,
+	.name = "asus_acpi",
 	.class = ACPI_HOTK_CLASS,
 	.ids = ACPI_HOTK_HID,
 	.ops = {
@@ -1117,6 +1127,8 @@
 		return W3V;
 	else if (strncmp(model, "W5A", 3) == 0)
 		return W5A;
+	else if (strncmp(model, "A4S", 3) == 0)
+		return A4S;
 	else
 		return END_MODEL;
 }
@@ -1365,10 +1377,6 @@
 	if (acpi_disabled)
 		return -ENODEV;
 
-	if (!acpi_specific_hotkey_enabled) {
-		printk(KERN_ERR "Using generic hotkey driver\n");
-		return -ENODEV;
-	}
 	asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir);
 	if (!asus_proc_dir) {
 		printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n");
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 2f4521a..e64c76c 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -42,7 +42,6 @@
 #define ACPI_BATTERY_COMPONENT		0x00040000
 #define ACPI_BATTERY_CLASS		"battery"
 #define ACPI_BATTERY_HID		"PNP0C0A"
-#define ACPI_BATTERY_DRIVER_NAME	"ACPI Battery Driver"
 #define ACPI_BATTERY_DEVICE_NAME	"Battery"
 #define ACPI_BATTERY_FILE_INFO		"info"
 #define ACPI_BATTERY_FILE_STATUS	"state"
@@ -53,10 +52,10 @@
 #define ACPI_BATTERY_UNITS_AMPS		"mA"
 
 #define _COMPONENT		ACPI_BATTERY_COMPONENT
-ACPI_MODULE_NAME("acpi_battery")
+ACPI_MODULE_NAME("battery");
 
-    MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION(ACPI_BATTERY_DRIVER_NAME);
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION("ACPI Battery Driver");
 MODULE_LICENSE("GPL");
 
 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
@@ -67,7 +66,7 @@
 static int acpi_battery_resume(struct acpi_device *device);
 
 static struct acpi_driver acpi_battery_driver = {
-	.name = ACPI_BATTERY_DRIVER_NAME,
+	.name = "battery",
 	.class = ACPI_BATTERY_CLASS,
 	.ids = ACPI_BATTERY_HID,
 	.ops = {
@@ -324,6 +323,13 @@
 	return result;
 }
 
+static void acpi_battery_check_present(struct acpi_battery *battery)
+{
+	if (!battery->flags.present) {
+		acpi_battery_check(battery);
+	}
+}
+
 /* --------------------------------------------------------------------------
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
@@ -340,6 +346,8 @@
 	if (!battery)
 		goto end;
 
+	acpi_battery_check_present(battery);
+
 	if (battery->flags.present)
 		seq_printf(seq, "present:                 yes\n");
 	else {
@@ -424,6 +432,8 @@
 	if (!battery)
 		goto end;
 
+	acpi_battery_check_present(battery);
+
 	if (battery->flags.present)
 		seq_printf(seq, "present:                 yes\n");
 	else {
@@ -499,6 +509,8 @@
 	if (!battery)
 		goto end;
 
+	acpi_battery_check_present(battery);
+
 	if (!battery->flags.present) {
 		seq_printf(seq, "present:                 no\n");
 		goto end;
@@ -536,6 +548,8 @@
 	if (!battery || (count > sizeof(alarm_string) - 1))
 		return -EINVAL;
 
+	acpi_battery_check_present(battery);
+
 	if (!battery->flags.present)
 		return -ENODEV;
 
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
index 91082ce..fb3f31b 100644
--- a/drivers/acpi/bay.c
+++ b/drivers/acpi/bay.c
@@ -32,11 +32,9 @@
 #include <asm/uaccess.h>
 #include <linux/platform_device.h>
 
-#define ACPI_BAY_DRIVER_NAME "ACPI Removable Drive Bay Driver"
-
-ACPI_MODULE_NAME("bay")
+ACPI_MODULE_NAME("bay");
 MODULE_AUTHOR("Kristen Carlson Accardi");
-MODULE_DESCRIPTION(ACPI_BAY_DRIVER_NAME);
+MODULE_DESCRIPTION("ACPI Removable Drive Bay Driver");
 MODULE_LICENSE("GPL");
 #define ACPI_BAY_CLASS "bay"
 #define ACPI_BAY_COMPONENT	0x10000000
@@ -47,18 +45,6 @@
 	acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\
 	printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); }
 static void bay_notify(acpi_handle handle, u32 event, void *data);
-static int acpi_bay_add(struct acpi_device *device);
-static int acpi_bay_remove(struct acpi_device *device, int type);
-
-static struct acpi_driver acpi_bay_driver = {
-	.name = ACPI_BAY_DRIVER_NAME,
-	.class = ACPI_BAY_CLASS,
-	.ids = ACPI_BAY_HID,
-	.ops = {
-		.add = acpi_bay_add,
-		.remove = acpi_bay_remove,
-		},
-};
 
 struct bay {
 	acpi_handle handle;
@@ -234,14 +220,6 @@
 }
 EXPORT_SYMBOL_GPL(eject_removable_drive);
 
-static int acpi_bay_add(struct acpi_device *device)
-{
-	bay_dprintk(device->handle, "adding bay device");
-	strcpy(acpi_device_name(device), "Dockable Bay");
-	strcpy(acpi_device_class(device), "bay");
-	return 0;
-}
-
 static int acpi_bay_add_fs(struct bay *bay)
 {
 	int ret;
@@ -303,7 +281,7 @@
 
 	/* initialize platform device stuff */
 	pdev = platform_device_register_simple(ACPI_BAY_CLASS, id, NULL, 0);
-	if (pdev == NULL) {
+	if (IS_ERR(pdev)) {
 		printk(KERN_ERR PREFIX "Error registering bay device\n");
 		goto bay_add_err;
 	}
@@ -339,52 +317,6 @@
 	return -ENODEV;
 }
 
-static int acpi_bay_remove(struct acpi_device *device, int type)
-{
-	/*** FIXME: do something here */
-	return 0;
-}
-
-/**
- * bay_create_acpi_device - add new devices to acpi
- * @handle - handle of the device to add
- *
- *  This function will create a new acpi_device for the given
- *  handle if one does not exist already.  This should cause
- *  acpi to scan for drivers for the given devices, and call
- *  matching driver's add routine.
- *
- *  Returns a pointer to the acpi_device corresponding to the handle.
- */
-static struct acpi_device * bay_create_acpi_device(acpi_handle handle)
-{
-	struct acpi_device *device = NULL;
-	struct acpi_device *parent_device;
-	acpi_handle parent;
-	int ret;
-
-	bay_dprintk(handle, "Trying to get device");
-	if (acpi_bus_get_device(handle, &device)) {
-		/*
-		 * no device created for this object,
-		 * so we should create one.
-		 */
-		bay_dprintk(handle, "No device for handle");
-		acpi_get_parent(handle, &parent);
-		if (acpi_bus_get_device(parent, &parent_device))
-			parent_device = NULL;
-
-		ret = acpi_bus_add(&device, parent_device, handle,
-			ACPI_BUS_TYPE_DEVICE);
-		if (ret) {
-			pr_debug("error adding bus, %x\n",
-				-ret);
-			return NULL;
-		}
-	}
-	return device;
-}
-
 /**
  * bay_notify - act upon an acpi bay notification
  * @handle: the bay handle
@@ -394,38 +326,19 @@
  */
 static void bay_notify(acpi_handle handle, u32 event, void *data)
 {
-	struct acpi_device *dev;
+	struct bay *bay_dev = (struct bay *)data;
+	struct device *dev = &bay_dev->pdev->dev;
 
 	bay_dprintk(handle, "Bay event");
 
 	switch(event) {
 	case ACPI_NOTIFY_BUS_CHECK:
-		printk("Bus Check\n");
 	case ACPI_NOTIFY_DEVICE_CHECK:
-		printk("Device Check\n");
-		dev = bay_create_acpi_device(handle);
-		if (dev)
-			acpi_bus_generate_event(dev, event, 0);
-		else
-			printk("No device for generating event\n");
-		/* wouldn't it be a good idea to just rescan SATA
-		 * right here?
-		 */
-		break;
 	case ACPI_NOTIFY_EJECT_REQUEST:
-		printk("Eject request\n");
-		dev = bay_create_acpi_device(handle);
-		if (dev)
-			acpi_bus_generate_event(dev, event, 0);
-		else
-			printk("No device for generating eventn");
-
-		/* wouldn't it be a good idea to just call the
-		 * eject_device here if we were a SATA device?
-		 */
+		kobject_uevent(&dev->kobj, KOBJ_CHANGE);
 		break;
 	default:
-		printk("unknown event %d\n", event);
+		printk(KERN_ERR PREFIX "Bay: unknown event %d\n", event);
 	}
 }
 
@@ -457,10 +370,6 @@
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 		ACPI_UINT32_MAX, find_bay, &bays, NULL);
 
-	if (bays)
-		if ((acpi_bus_register_driver(&acpi_bay_driver) < 0))
-			printk(KERN_ERR "Unable to register bay driver\n");
-
 	if (!bays)
 		return -ENODEV;
 
@@ -481,8 +390,6 @@
 		kfree(bay->name);
 		kfree(bay);
 	}
-
-	acpi_bus_unregister_driver(&acpi_bay_driver);
 }
 
 postcore_initcall(bay_init);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index c26468d..dd49ea0 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -39,7 +39,7 @@
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT		ACPI_BUS_COMPONENT
-ACPI_MODULE_NAME("acpi_bus")
+ACPI_MODULE_NAME("bus");
 #ifdef	CONFIG_X86
 extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger);
 #endif
@@ -147,7 +147,7 @@
 			*state = ACPI_STATE_D0;
 	} else {
 		/*
-		 * Get the device's power state either directly (via _PSC) or 
+		 * Get the device's power state either directly (via _PSC) or
 		 * indirectly (via power resources).
 		 */
 		if (device->power.flags.explicit_get) {
@@ -199,15 +199,14 @@
 	 * Get device's current power state if it's unknown
 	 * This means device power state isn't initialized or previous setting failed
 	 */
-	if (!device->flags.force_power_state) {
-		if (device->power.state == ACPI_STATE_UNKNOWN)
-			acpi_bus_get_power(device->handle, &device->power.state);
-		if (state == device->power.state) {
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
-					  state));
-			return 0;
-		}
+	if ((device->power.state == ACPI_STATE_UNKNOWN) || device->flags.force_power_state)
+		acpi_bus_get_power(device->handle, &device->power.state);
+	if ((state == device->power.state) && !device->flags.force_power_state) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
+				  state));
+		return 0;
 	}
+
 	if (!device->power.states[state].flags.valid) {
 		printk(KERN_WARNING PREFIX "Device does not support D%d\n", state);
 		return -ENODEV;
@@ -462,7 +461,7 @@
 				  "Received BUS CHECK notification for device [%s]\n",
 				  device->pnp.bus_id));
 		result = acpi_bus_check_scope(device);
-		/* 
+		/*
 		 * TBD: We'll need to outsource certain events to non-ACPI
 		 *      drivers via the device manager (device.c).
 		 */
@@ -473,7 +472,7 @@
 				  "Received DEVICE CHECK notification for device [%s]\n",
 				  device->pnp.bus_id));
 		result = acpi_bus_check_device(device, NULL);
-		/* 
+		/*
 		 * TBD: We'll need to outsource certain events to non-ACPI
 		 *      drivers via the device manager (device.c).
 		 */
@@ -543,7 +542,7 @@
 	char *message = NULL;
 
 
-	/* 
+	/*
 	 * Let the system know what interrupt model we are using by
 	 * evaluating the \_PIC object, if exists.
 	 */
@@ -684,7 +683,7 @@
 	 * the EC device is found in the namespace (i.e. before acpi_initialize_objects()
 	 * is called).
 	 *
-	 * This is accomplished by looking for the ECDT table, and getting 
+	 * This is accomplished by looking for the ECDT table, and getting
 	 * the EC parameters out of that.
 	 */
 	status = acpi_ec_ecdt_probe();
@@ -699,6 +698,9 @@
 
 	printk(KERN_INFO PREFIX "Interpreter enabled\n");
 
+	/* Initialize sleep structures */
+	acpi_sleep_init();
+
 	/*
 	 * Get the system interrupt model and evaluate \_PIC.
 	 */
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index c726612..cb4110b 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -34,7 +34,6 @@
 #include <acpi/acpi_drivers.h>
 
 #define ACPI_BUTTON_COMPONENT		0x00080000
-#define ACPI_BUTTON_DRIVER_NAME		"ACPI Button Driver"
 #define ACPI_BUTTON_CLASS		"button"
 #define ACPI_BUTTON_FILE_INFO		"info"
 #define ACPI_BUTTON_FILE_STATE		"state"
@@ -61,10 +60,10 @@
 #define ACPI_BUTTON_TYPE_LID		0x05
 
 #define _COMPONENT		ACPI_BUTTON_COMPONENT
-ACPI_MODULE_NAME("acpi_button")
+ACPI_MODULE_NAME("button");
 
 MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME);
+MODULE_DESCRIPTION("ACPI Button Driver");
 MODULE_LICENSE("GPL");
 
 static int acpi_button_add(struct acpi_device *device);
@@ -73,7 +72,7 @@
 static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
 
 static struct acpi_driver acpi_button_driver = {
-	.name = ACPI_BUTTON_DRIVER_NAME,
+	.name = "button",
 	.class = ACPI_BUTTON_CLASS,
 	.ids = "button_power,button_sleep,PNP0C0D,PNP0C0C,PNP0C0E",
 	.ops = {
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c
index 4a9b7bf..f9db4f4 100644
--- a/drivers/acpi/cm_sbs.c
+++ b/drivers/acpi/cm_sbs.c
@@ -31,7 +31,7 @@
 #include <acpi/actypes.h>
 #include <acpi/acutils.h>
 
-ACPI_MODULE_NAME("cm_sbs")
+ACPI_MODULE_NAME("cm_sbs");
 #define ACPI_AC_CLASS		"ac_adapter"
 #define ACPI_BATTERY_CLASS	"battery"
 #define ACPI_SBS_COMPONENT	0x00080000
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 69a68fd..0930d94 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -35,7 +35,6 @@
 #include <acpi/acpi_drivers.h>
 #include <acpi/container.h>
 
-#define ACPI_CONTAINER_DRIVER_NAME	"ACPI container driver"
 #define ACPI_CONTAINER_DEVICE_NAME	"ACPI container device"
 #define ACPI_CONTAINER_CLASS		"container"
 
@@ -44,10 +43,10 @@
 
 #define ACPI_CONTAINER_COMPONENT	0x01000000
 #define _COMPONENT			ACPI_CONTAINER_COMPONENT
-ACPI_MODULE_NAME("acpi_container")
+ACPI_MODULE_NAME("container");
 
-    MODULE_AUTHOR("Anil S Keshavamurthy");
-MODULE_DESCRIPTION(ACPI_CONTAINER_DRIVER_NAME);
+MODULE_AUTHOR("Anil S Keshavamurthy");
+MODULE_DESCRIPTION("ACPI container driver");
 MODULE_LICENSE("GPL");
 
 #define ACPI_STA_PRESENT		(0x00000001)
@@ -56,7 +55,7 @@
 static int acpi_container_remove(struct acpi_device *device, int type);
 
 static struct acpi_driver acpi_container_driver = {
-	.name = ACPI_CONTAINER_DRIVER_NAME,
+	.name = "container",
 	.class = ACPI_CONTAINER_CLASS,
 	.ids = "ACPI0004,PNP0A05,PNP0A06",
 	.ops = {
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index d48f65a..bf513e0 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -12,7 +12,7 @@
 #include <acpi/acglobal.h>
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
-ACPI_MODULE_NAME("debug")
+ACPI_MODULE_NAME("debug");
 
 #ifdef MODULE_PARAM_PREFIX
 #undef MODULE_PARAM_PREFIX
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index 1cbe619..1683e5c 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -231,10 +231,8 @@
 		 * Obtain the method mutex if necessary. Do not acquire mutex for a
 		 * recursive call.
 		 */
-		if (!walk_state ||
-		    !obj_desc->method.mutex->mutex.owner_thread ||
-		    (walk_state->thread !=
-		     obj_desc->method.mutex->mutex.owner_thread)) {
+		if (acpi_os_get_thread_id() !=
+		    obj_desc->method.mutex->mutex.owner_thread_id) {
 			/*
 			 * Acquire the method mutex. This releases the interpreter if we
 			 * block (and reacquires it before it returns)
@@ -248,14 +246,14 @@
 			}
 
 			/* Update the mutex and walk info and save the original sync_level */
+			obj_desc->method.mutex->mutex.owner_thread_id =
+				acpi_os_get_thread_id();
 
 			if (walk_state) {
 				obj_desc->method.mutex->mutex.
 				    original_sync_level =
 				    walk_state->thread->current_sync_level;
 
-				obj_desc->method.mutex->mutex.owner_thread =
-				    walk_state->thread;
 				walk_state->thread->current_sync_level =
 				    obj_desc->method.sync_level;
 			} else {
@@ -569,7 +567,7 @@
 
 			acpi_os_release_mutex(method_desc->method.mutex->mutex.
 					      os_mutex);
-			method_desc->method.mutex->mutex.owner_thread = NULL;
+			method_desc->method.mutex->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;
 		}
 	}
 
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 688e83a..54a697f 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -32,11 +32,11 @@
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
-#define ACPI_DOCK_DRIVER_NAME "ACPI Dock Station Driver"
+#define ACPI_DOCK_DRIVER_DESCRIPTION "ACPI Dock Station Driver"
 
-ACPI_MODULE_NAME("dock")
+ACPI_MODULE_NAME("dock");
 MODULE_AUTHOR("Kristen Carlson Accardi");
-MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_NAME);
+MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION);
 MODULE_LICENSE("GPL");
 
 static struct atomic_notifier_head dock_notifier_list;
@@ -741,7 +741,7 @@
 		goto dock_add_err;
 	}
 
-	printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_NAME);
+	printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_DESCRIPTION);
 
 	return 0;
 
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 743ce27..ab68883 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -38,11 +38,10 @@
 #include <acpi/actypes.h>
 
 #define _COMPONENT		ACPI_EC_COMPONENT
-ACPI_MODULE_NAME("acpi_ec")
+ACPI_MODULE_NAME("ec");
 #define ACPI_EC_COMPONENT		0x00100000
 #define ACPI_EC_CLASS			"embedded_controller"
 #define ACPI_EC_HID			"PNP0C09"
-#define ACPI_EC_DRIVER_NAME		"ACPI Embedded Controller Driver"
 #define ACPI_EC_DEVICE_NAME		"Embedded Controller"
 #define ACPI_EC_FILE_INFO		"info"
 #undef PREFIX
@@ -80,7 +79,7 @@
 static int acpi_ec_add(struct acpi_device *device);
 
 static struct acpi_driver acpi_ec_driver = {
-	.name = ACPI_EC_DRIVER_NAME,
+	.name = "ec",
 	.class = ACPI_EC_CLASS,
 	.ids = ACPI_EC_HID,
 	.ops = {
@@ -280,8 +279,10 @@
 	mutex_lock(&ec->lock);
 	if (ec->global_lock) {
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
-		if (ACPI_FAILURE(status))
+		if (ACPI_FAILURE(status)) {
+			mutex_unlock(&ec->lock);
 			return -ENODEV;
+		}
 	}
 
 	/* Make sure GPE is enabled before doing transaction */
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index 959a893..3b23562 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -13,7 +13,7 @@
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
-ACPI_MODULE_NAME("event")
+ACPI_MODULE_NAME("event");
 
 /* Global vars for handling event proc entry */
 static DEFINE_SPINLOCK(acpi_system_event_lock);
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index dfac3ec..635ba44 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -636,17 +636,6 @@
 		}
 	}
 
-	if (!acpi_gbl_system_awake_and_running) {
-		/*
-		 * We just woke up because of a wake GPE. Disable any further GPEs
-		 * until we are fully up and running (Only wake GPEs should be enabled
-		 * at this time, but we just brute-force disable them all.)
-		 * 1) We must disable this particular wake GPE so it won't fire again
-		 * 2) We want to disable all wake GPEs, since we are now awake
-		 */
-		(void)acpi_hw_disable_all_gpes();
-	}
-
 	/*
 	 * Dispatch the GPE to either an installed handler, or the control method
 	 * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index 1b784ffe..d572700 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -196,12 +196,11 @@
 		notify_info->notify.value = (u16) notify_value;
 		notify_info->notify.handler_obj = handler_obj;
 
-		status =
-		    acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch,
-				    notify_info);
-		if (ACPI_FAILURE(status)) {
-			acpi_ut_delete_generic_state(notify_info);
-		}
+		acpi_ex_relinquish_interpreter();
+
+		acpi_ev_notify_dispatch(notify_info);
+
+		acpi_ex_reacquire_interpreter();
 	}
 
 	if (!handler_obj) {
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index 68d283f..1a73c14 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -134,7 +134,7 @@
 static struct acpi_exdump_info acpi_ex_dump_mutex[5] = {
 	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL},
 	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"},
-	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread_id), "Owner Thread"},
 	{ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth),
 	 "Acquire Depth"},
 	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.os_mutex), "OsMutex"}
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index 5101bad..4eb883b 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -66,10 +66,9 @@
  *
  ******************************************************************************/
 
-void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc)
+void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc,
+			  struct acpi_thread_state *thread)
 {
-	struct acpi_thread_state *thread = obj_desc->mutex.owner_thread;
-
 	if (!thread) {
 		return;
 	}
@@ -174,16 +173,13 @@
 
 	/* Support for multiple acquires by the owning thread */
 
-	if (obj_desc->mutex.owner_thread) {
-		if (obj_desc->mutex.owner_thread->thread_id ==
-		    walk_state->thread->thread_id) {
-			/*
-			 * The mutex is already owned by this thread, just increment the
-			 * acquisition depth
-			 */
-			obj_desc->mutex.acquisition_depth++;
-			return_ACPI_STATUS(AE_OK);
-		}
+	if (obj_desc->mutex.owner_thread_id == acpi_os_get_thread_id()) {
+		/*
+		 * The mutex is already owned by this thread, just increment the
+		 * acquisition depth
+		 */
+		obj_desc->mutex.acquisition_depth++;
+		return_ACPI_STATUS(AE_OK);
 	}
 
 	/* Acquire the mutex, wait if necessary. Special case for Global Lock */
@@ -206,7 +202,7 @@
 
 	/* Have the mutex: update mutex and walk info and save the sync_level */
 
-	obj_desc->mutex.owner_thread = walk_state->thread;
+	obj_desc->mutex.owner_thread_id = acpi_os_get_thread_id();
 	obj_desc->mutex.acquisition_depth = 1;
 	obj_desc->mutex.original_sync_level =
 	    walk_state->thread->current_sync_level;
@@ -246,7 +242,7 @@
 
 	/* The mutex must have been previously acquired in order to release it */
 
-	if (!obj_desc->mutex.owner_thread) {
+	if (!obj_desc->mutex.owner_thread_id) {
 		ACPI_ERROR((AE_INFO,
 			    "Cannot release Mutex [%4.4s], not acquired",
 			    acpi_ut_get_node_name(obj_desc->mutex.node)));
@@ -266,14 +262,14 @@
 	 * The Mutex is owned, but this thread must be the owner.
 	 * Special case for Global Lock, any thread can release
 	 */
-	if ((obj_desc->mutex.owner_thread->thread_id !=
+	if ((obj_desc->mutex.owner_thread_id !=
 	     walk_state->thread->thread_id)
 	    && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) {
 		ACPI_ERROR((AE_INFO,
 			    "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
 			    (unsigned long)walk_state->thread->thread_id,
 			    acpi_ut_get_node_name(obj_desc->mutex.node),
-			    (unsigned long)obj_desc->mutex.owner_thread->thread_id));
+			    (unsigned long)obj_desc->mutex.owner_thread_id));
 		return_ACPI_STATUS(AE_AML_NOT_OWNER);
 	}
 
@@ -300,7 +296,7 @@
 
 	/* Unlink the mutex from the owner's list */
 
-	acpi_ex_unlink_mutex(obj_desc);
+	acpi_ex_unlink_mutex(obj_desc, walk_state->thread);
 
 	/* Release the mutex, special case for Global Lock */
 
@@ -312,7 +308,7 @@
 
 	/* Update the mutex and restore sync_level */
 
-	obj_desc->mutex.owner_thread = NULL;
+	obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;
 	walk_state->thread->current_sync_level =
 	    obj_desc->mutex.original_sync_level;
 
@@ -367,7 +363,7 @@
 
 		/* Mark mutex unowned */
 
-		obj_desc->mutex.owner_thread = NULL;
+		obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;
 
 		/* Update Thread sync_level (Last mutex is the important one) */
 
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index af22fdf..ec655c5 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -36,14 +36,13 @@
 
 #define ACPI_FAN_COMPONENT		0x00200000
 #define ACPI_FAN_CLASS			"fan"
-#define ACPI_FAN_DRIVER_NAME		"ACPI Fan Driver"
 #define ACPI_FAN_FILE_STATE		"state"
 
 #define _COMPONENT		ACPI_FAN_COMPONENT
-ACPI_MODULE_NAME("acpi_fan")
+ACPI_MODULE_NAME("fan");
 
-    MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION(ACPI_FAN_DRIVER_NAME);
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION("ACPI Fan Driver");
 MODULE_LICENSE("GPL");
 
 static int acpi_fan_add(struct acpi_device *device);
@@ -52,7 +51,7 @@
 static int acpi_fan_resume(struct acpi_device *device);
 
 static struct acpi_driver acpi_fan_driver = {
-	.name = ACPI_FAN_DRIVER_NAME,
+	.name = "fan",
 	.class = ACPI_FAN_CLASS,
 	.ids = "PNP0C0B",
 	.ops = {
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 7b6c9ff..4334c20 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -241,3 +241,65 @@
 }
 
 arch_initcall(init_acpi_device_notify);
+
+
+#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
+
+/* Every ACPI platform has a mc146818 compatible "cmos rtc".  Here we find
+ * its device node and pass extra config data.  This helps its driver use
+ * capabilities that the now-obsolete mc146818 didn't have, and informs it
+ * that this board's RTC is wakeup-capable (per ACPI spec).
+ */
+#include <linux/mc146818rtc.h>
+
+static struct cmos_rtc_board_info rtc_info;
+
+
+/* PNP devices are registered in a subsys_initcall();
+ * ACPI specifies the PNP IDs to use.
+ */
+#include <linux/pnp.h>
+
+static int __init pnp_match(struct device *dev, void *data)
+{
+	static const char *ids[] = { "PNP0b00", "PNP0b01", "PNP0b02", };
+	struct pnp_dev *pnp = to_pnp_dev(dev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ids); i++) {
+		if (compare_pnp_id(pnp->id, ids[i]) != 0)
+			return 1;
+	}
+	return 0;
+}
+
+static struct device *__init get_rtc_dev(void)
+{
+	return bus_find_device(&pnp_bus_type, NULL, NULL, pnp_match);
+}
+
+static int __init acpi_rtc_init(void)
+{
+	struct device *dev = get_rtc_dev();
+
+	if (dev) {
+		rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
+		rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
+		rtc_info.rtc_century = acpi_gbl_FADT.century;
+
+		/* NOTE:  acpi_gbl_FADT->rtcs4 is NOT currently useful */
+
+		dev->platform_data = &rtc_info;
+
+		/* RTC always wakes from S1/S2/S3, and often S4/STD */
+		device_init_wakeup(dev, 1);
+
+		put_device(dev);
+	} else
+		pr_debug("ACPI: RTC unavailable?\n");
+	return 0;
+}
+/* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */
+fs_initcall(acpi_rtc_init);
+
+#endif
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 57901ca..8fa9312 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -235,6 +235,14 @@
 				"While executing method _SST"));
 	}
 
+	/*
+	 * 1) Disable/Clear all GPEs
+	 */
+	status = acpi_hw_disable_all_gpes();
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
 	return_ACPI_STATUS(AE_OK);
 }
 
@@ -290,13 +298,8 @@
 	}
 
 	/*
-	 * 1) Disable/Clear all GPEs
 	 * 2) Enable all wakeup GPEs
 	 */
-	status = acpi_hw_disable_all_gpes();
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
 	acpi_gbl_system_awake_and_running = FALSE;
 
 	status = acpi_hw_enable_all_wakeup_gpes();
diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c
deleted file mode 100644
index 8edfb92..0000000
--- a/drivers/acpi/hotkey.c
+++ /dev/null
@@ -1,1042 +0,0 @@
-/*
- *  hotkey.c - ACPI Hotkey Driver ($Revision: 0.2 $)
- *
- *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or (at
- *  your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/sched.h>
-#include <linux/kmod.h>
-#include <linux/seq_file.h>
-#include <acpi/acpi_drivers.h>
-#include <acpi/acpi_bus.h>
-#include <asm/uaccess.h>
-
-#define HOTKEY_ACPI_VERSION "0.1"
-
-#define HOTKEY_PROC "hotkey"
-#define HOTKEY_EV_CONFIG    "event_config"
-#define HOTKEY_PL_CONFIG    "poll_config"
-#define HOTKEY_ACTION   "action"
-#define HOTKEY_INFO "info"
-
-#define ACPI_HOTK_NAME          "Generic Hotkey Driver"
-#define ACPI_HOTK_CLASS         "Hotkey"
-#define ACPI_HOTK_DEVICE_NAME   "Hotkey"
-#define ACPI_HOTK_HID           "Unknown?"
-#define ACPI_HOTKEY_COMPONENT   0x20000000
-
-#define ACPI_HOTKEY_EVENT   0x1
-#define ACPI_HOTKEY_POLLING 0x2
-#define ACPI_UNDEFINED_EVENT    0xf
-
-#define RESULT_STR_LEN	    80
-
-#define ACTION_METHOD	0
-#define POLL_METHOD	1
-
-#define IS_EVENT(e)       	((e) <= 10000 && (e) >0)
-#define IS_POLL(e)      	((e) > 10000)
-#define IS_OTHERS(e)		((e)<=0 || (e)>=20000)
-#define _COMPONENT              ACPI_HOTKEY_COMPONENT
-ACPI_MODULE_NAME("acpi_hotkey")
-
-    MODULE_AUTHOR("luming.yu@intel.com");
-MODULE_DESCRIPTION(ACPI_HOTK_NAME);
-MODULE_LICENSE("GPL");
-
-/*  standardized internal hotkey number/event  */
-enum {
-	/* Video Extension event */
-	HK_EVENT_CYCLE_OUTPUT_DEVICE = 0x80,
-	HK_EVENT_OUTPUT_DEVICE_STATUS_CHANGE,
-	HK_EVENT_CYCLE_DISPLAY_OUTPUT,
-	HK_EVENT_NEXT_DISPLAY_OUTPUT,
-	HK_EVENT_PREVIOUS_DISPLAY_OUTPUT,
-	HK_EVENT_CYCLE_BRIGHTNESS,
-	HK_EVENT_INCREASE_BRIGHTNESS,
-	HK_EVENT_DECREASE_BRIGHTNESS,
-	HK_EVENT_ZERO_BRIGHTNESS,
-	HK_EVENT_DISPLAY_DEVICE_OFF,
-
-	/* Snd Card event */
-	HK_EVENT_VOLUME_MUTE,
-	HK_EVENT_VOLUME_INCLREASE,
-	HK_EVENT_VOLUME_DECREASE,
-
-	/* running state control */
-	HK_EVENT_ENTERRING_S3,
-	HK_EVENT_ENTERRING_S4,
-	HK_EVENT_ENTERRING_S5,
-};
-
-enum conf_entry_enum {
-	bus_handle = 0,
-	bus_method = 1,
-	action_handle = 2,
-	method = 3,
-	LAST_CONF_ENTRY
-};
-
-/*  procdir we use */
-static struct proc_dir_entry *hotkey_proc_dir;
-static struct proc_dir_entry *hotkey_config;
-static struct proc_dir_entry *hotkey_poll_config;
-static struct proc_dir_entry *hotkey_action;
-static struct proc_dir_entry *hotkey_info;
-
-/* linkage for all type of hotkey */
-struct acpi_hotkey_link {
-	struct list_head entries;
-	int hotkey_type;	/* event or polling based hotkey  */
-	int hotkey_standard_num;	/* standardized hotkey(event) number */
-};
-
-/* event based hotkey */
-struct acpi_event_hotkey {
-	struct acpi_hotkey_link hotkey_link;
-	int flag;
-	acpi_handle bus_handle;	/* bus to install notify handler */
-	int external_hotkey_num;	/* external hotkey/event number */
-	acpi_handle action_handle;	/* acpi handle attached aml action method */
-	char *action_method;	/* action method */
-};
-
-/*
- * There are two ways to poll status
- * 1. directy call read_xxx method, without any arguments passed in
- * 2. call write_xxx method, with arguments passed in, you need
- * the result is saved in acpi_polling_hotkey.poll_result.
- * anthoer read command through polling interface.
- *
- */
-
-/* polling based hotkey */
-struct acpi_polling_hotkey {
-	struct acpi_hotkey_link hotkey_link;
-	int flag;
-	acpi_handle poll_handle;	/* acpi handle attached polling method */
-	char *poll_method;	/* poll method */
-	acpi_handle action_handle;	/* acpi handle attached action method */
-	char *action_method;	/* action method */
-	union acpi_object *poll_result;	/* polling_result */
-	struct proc_dir_entry *proc;
-};
-
-/* hotkey object union */
-union acpi_hotkey {
-	struct list_head entries;
-	struct acpi_hotkey_link link;
-	struct acpi_event_hotkey event_hotkey;
-	struct acpi_polling_hotkey poll_hotkey;
-};
-
-/* hotkey object list */
-struct acpi_hotkey_list {
-	struct list_head *entries;
-	int count;
-};
-
-static int auto_hotkey_add(struct acpi_device *device);
-static int auto_hotkey_remove(struct acpi_device *device, int type);
-
-static struct acpi_driver hotkey_driver = {
-	.name = ACPI_HOTK_NAME,
-	.class = ACPI_HOTK_CLASS,
-	.ids = ACPI_HOTK_HID,
-	.ops = {
-		.add = auto_hotkey_add,
-		.remove = auto_hotkey_remove,
-		},
-};
-
-static void free_hotkey_device(union acpi_hotkey *key);
-static void free_hotkey_buffer(union acpi_hotkey *key);
-static void free_poll_hotkey_buffer(union acpi_hotkey *key);
-static int hotkey_open_config(struct inode *inode, struct file *file);
-static int hotkey_poll_open_config(struct inode *inode, struct file *file);
-static ssize_t hotkey_write_config(struct file *file,
-				   const char __user * buffer,
-				   size_t count, loff_t * data);
-static int hotkey_info_open_fs(struct inode *inode, struct file *file);
-static int hotkey_action_open_fs(struct inode *inode, struct file *file);
-static ssize_t hotkey_execute_aml_method(struct file *file,
-					 const char __user * buffer,
-					 size_t count, loff_t * data);
-static int hotkey_config_seq_show(struct seq_file *seq, void *offset);
-static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset);
-static int hotkey_polling_open_fs(struct inode *inode, struct file *file);
-static union acpi_hotkey *get_hotkey_by_event(struct
-					      acpi_hotkey_list
-					      *hotkey_list, int event);
-
-/* event based config */
-static const struct file_operations hotkey_config_fops = {
-	.open = hotkey_open_config,
-	.read = seq_read,
-	.write = hotkey_write_config,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-/* polling based config */
-static const struct file_operations hotkey_poll_config_fops = {
-	.open = hotkey_poll_open_config,
-	.read = seq_read,
-	.write = hotkey_write_config,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-/* hotkey driver info */
-static const struct file_operations hotkey_info_fops = {
-	.open = hotkey_info_open_fs,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-/* action */
-static const struct file_operations hotkey_action_fops = {
-	.open = hotkey_action_open_fs,
-	.read = seq_read,
-	.write = hotkey_execute_aml_method,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-/* polling results */
-static const struct file_operations hotkey_polling_fops = {
-	.open = hotkey_polling_open_fs,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-struct acpi_hotkey_list global_hotkey_list;	/* link all ev or pl hotkey  */
-struct list_head hotkey_entries;	/* head of the list of hotkey_list */
-
-static int hotkey_info_seq_show(struct seq_file *seq, void *offset)
-{
-
-	seq_printf(seq, "Hotkey generic driver ver: %s\n", HOTKEY_ACPI_VERSION);
-
-	return 0;
-}
-
-static int hotkey_info_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, hotkey_info_seq_show, PDE(inode)->data);
-}
-
-static char *format_result(union acpi_object *object)
-{
-	char *buf;
-
-	buf = kzalloc(RESULT_STR_LEN, GFP_KERNEL);
-	if (!buf)
-		return NULL;
-	/* Now, just support integer type */
-	if (object->type == ACPI_TYPE_INTEGER)
-		sprintf(buf, "%d\n", (u32) object->integer.value);
-	return buf;
-}
-
-static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
-{
-	struct acpi_polling_hotkey *poll_hotkey = seq->private;
-	char *buf;
-
-
-	if (poll_hotkey->poll_result) {
-		buf = format_result(poll_hotkey->poll_result);
-		if (buf)
-			seq_printf(seq, "%s", buf);
-		kfree(buf);
-	}
-	return 0;
-}
-
-static int hotkey_polling_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, hotkey_polling_seq_show, PDE(inode)->data);
-}
-
-static int hotkey_action_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, hotkey_info_seq_show, PDE(inode)->data);
-}
-
-/* Mapping external hotkey number to standardized hotkey event num */
-static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list)
-{
-	struct list_head *entries;
-	int val = -1;
-
-
-	list_for_each(entries, list->entries) {
-		union acpi_hotkey *key =
-		    container_of(entries, union acpi_hotkey, entries);
-		if (key->link.hotkey_type == ACPI_HOTKEY_EVENT
-		    && key->event_hotkey.external_hotkey_num == event) {
-			val = key->link.hotkey_standard_num;
-			break;
-		}
-	}
-
-	return val;
-}
-
-static void
-acpi_hotkey_notify_handler(acpi_handle handle, u32 event, void *data)
-{
-	struct acpi_device *device = NULL;
-	u32 internal_event;
-
-
-	if (acpi_bus_get_device(handle, &device))
-		return;
-
-	internal_event = hotkey_get_internal_event(event, &global_hotkey_list);
-	acpi_bus_generate_event(device, internal_event, 0);
-
-	return;
-}
-
-/* Need to invent automatically hotkey add method */
-static int auto_hotkey_add(struct acpi_device *device)
-{
-	/* Implement me */
-	return 0;
-}
-
-/* Need to invent automatically hotkey remove method */
-static int auto_hotkey_remove(struct acpi_device *device, int type)
-{
-	/* Implement me */
-	return 0;
-}
-
-/* Create a proc file for each polling method */
-static int create_polling_proc(union acpi_hotkey *device)
-{
-	struct proc_dir_entry *proc;
-	char proc_name[80];
-	mode_t mode;
-
-	mode = S_IFREG | S_IRUGO | S_IWUGO;
-
-	sprintf(proc_name, "%d", device->link.hotkey_standard_num);
-	/*
-	   strcat(proc_name, device->poll_hotkey.poll_method);
-	 */
-	proc = create_proc_entry(proc_name, mode, hotkey_proc_dir);
-
-	if (!proc) {
-		return -ENODEV;
-	} else {
-		proc->proc_fops = &hotkey_polling_fops;
-		proc->owner = THIS_MODULE;
-		proc->data = device;
-		proc->uid = 0;
-		proc->gid = 0;
-		device->poll_hotkey.proc = proc;
-	}
-	return 0;
-}
-
-static int hotkey_add(union acpi_hotkey *device)
-{
-	int status = 0;
-	struct acpi_device *dev = NULL;
-
-
-	if (device->link.hotkey_type == ACPI_HOTKEY_EVENT) {
-		acpi_bus_get_device(device->event_hotkey.bus_handle, &dev);
-		status = acpi_install_notify_handler(dev->handle,
-						     ACPI_DEVICE_NOTIFY,
-						     acpi_hotkey_notify_handler,
-						     dev);
-	} else			/* Add polling hotkey */
-		create_polling_proc(device);
-
-	global_hotkey_list.count++;
-
-	list_add_tail(&device->link.entries, global_hotkey_list.entries);
-
-	return status;
-}
-
-static int hotkey_remove(union acpi_hotkey *device)
-{
-	struct list_head *entries, *next;
-
-
-	list_for_each_safe(entries, next, global_hotkey_list.entries) {
-		union acpi_hotkey *key =
-		    container_of(entries, union acpi_hotkey, entries);
-		if (key->link.hotkey_standard_num ==
-		    device->link.hotkey_standard_num) {
-			list_del(&key->link.entries);
-			free_hotkey_device(key);
-			global_hotkey_list.count--;
-			break;
-		}
-	}
-	kfree(device);
-	return 0;
-}
-
-static int hotkey_update(union acpi_hotkey *key)
-{
-	struct list_head *entries;
-
-
-	list_for_each(entries, global_hotkey_list.entries) {
-		union acpi_hotkey *tmp =
-		    container_of(entries, union acpi_hotkey, entries);
-		if (tmp->link.hotkey_standard_num ==
-		    key->link.hotkey_standard_num) {
-			if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
-				free_hotkey_buffer(tmp);
-				tmp->event_hotkey.bus_handle =
-				    key->event_hotkey.bus_handle;
-				tmp->event_hotkey.external_hotkey_num =
-				    key->event_hotkey.external_hotkey_num;
-				tmp->event_hotkey.action_handle =
-				    key->event_hotkey.action_handle;
-				tmp->event_hotkey.action_method =
-				    key->event_hotkey.action_method;
-				kfree(key);
-			} else {
-				/*
-				   char  proc_name[80];
-
-				   sprintf(proc_name, "%d", tmp->link.hotkey_standard_num);
-				   strcat(proc_name, tmp->poll_hotkey.poll_method);
-				   remove_proc_entry(proc_name,hotkey_proc_dir);
-				 */
-				free_poll_hotkey_buffer(tmp);
-				tmp->poll_hotkey.poll_handle =
-				    key->poll_hotkey.poll_handle;
-				tmp->poll_hotkey.poll_method =
-				    key->poll_hotkey.poll_method;
-				tmp->poll_hotkey.action_handle =
-				    key->poll_hotkey.action_handle;
-				tmp->poll_hotkey.action_method =
-				    key->poll_hotkey.action_method;
-				tmp->poll_hotkey.poll_result =
-				    key->poll_hotkey.poll_result;
-				/*
-				   create_polling_proc(tmp);
-				 */
-				kfree(key);
-			}
-			return 0;
-			break;
-		}
-	}
-
-	return -ENODEV;
-}
-
-static void free_hotkey_device(union acpi_hotkey *key)
-{
-	struct acpi_device *dev;
-
-
-	if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
-		acpi_bus_get_device(key->event_hotkey.bus_handle, &dev);
-		if (dev->handle)
-			acpi_remove_notify_handler(dev->handle,
-						   ACPI_DEVICE_NOTIFY,
-						   acpi_hotkey_notify_handler);
-		free_hotkey_buffer(key);
-	} else {
-		char proc_name[80];
-
-		sprintf(proc_name, "%d", key->link.hotkey_standard_num);
-		/*
-		   strcat(proc_name, key->poll_hotkey.poll_method);
-		 */
-		remove_proc_entry(proc_name, hotkey_proc_dir);
-		free_poll_hotkey_buffer(key);
-	}
-	kfree(key);
-	return;
-}
-
-static void free_hotkey_buffer(union acpi_hotkey *key)
-{
-	/* key would never be null, action method could be */
-	kfree(key->event_hotkey.action_method);
-}
-
-static void free_poll_hotkey_buffer(union acpi_hotkey *key)
-{
-	/* key would never be null, others could be*/
-	kfree(key->poll_hotkey.action_method);
-	kfree(key->poll_hotkey.poll_method);
-	kfree(key->poll_hotkey.poll_result);
-}
-static int
-init_hotkey_device(union acpi_hotkey *key, char **config_entry,
-		   int std_num, int external_num)
-{
-	acpi_handle tmp_handle;
-	acpi_status status = AE_OK;
-
-	if (std_num < 0 || IS_POLL(std_num) || !key)
-		goto do_fail;
-
-	if (!config_entry[bus_handle] || !config_entry[action_handle]
-			|| !config_entry[method])
-		goto do_fail;
-
-	key->link.hotkey_type = ACPI_HOTKEY_EVENT;
-	key->link.hotkey_standard_num = std_num;
-	key->event_hotkey.flag = 0;
-	key->event_hotkey.action_method = config_entry[method];
-
-	status = acpi_get_handle(NULL, config_entry[bus_handle],
-			   &(key->event_hotkey.bus_handle));
-	if (ACPI_FAILURE(status))
-		goto do_fail_zero;
-	key->event_hotkey.external_hotkey_num = external_num;
-	status = acpi_get_handle(NULL, config_entry[action_handle],
-			    &(key->event_hotkey.action_handle));
-	if (ACPI_FAILURE(status))
-		goto do_fail_zero;
-	status = acpi_get_handle(key->event_hotkey.action_handle,
-				 config_entry[method], &tmp_handle);
-	if (ACPI_FAILURE(status))
-		goto do_fail_zero;
-	return AE_OK;
-do_fail_zero:
-	key->event_hotkey.action_method = NULL;
-do_fail:
-	return -ENODEV;
-}
-
-static int
-init_poll_hotkey_device(union acpi_hotkey *key, char **config_entry,
-			int std_num)
-{
-	acpi_status status = AE_OK;
-	acpi_handle tmp_handle;
-
-	if (std_num < 0 || IS_EVENT(std_num) || !key)
-		goto do_fail;
-	if (!config_entry[bus_handle] ||!config_entry[bus_method] ||
-		!config_entry[action_handle] || !config_entry[method])
-		goto do_fail;
-
-	key->link.hotkey_type = ACPI_HOTKEY_POLLING;
-	key->link.hotkey_standard_num = std_num;
-	key->poll_hotkey.flag = 0;
-	key->poll_hotkey.poll_method = config_entry[bus_method];
-	key->poll_hotkey.action_method = config_entry[method];
-
-	status = acpi_get_handle(NULL, config_entry[bus_handle],
-		      &(key->poll_hotkey.poll_handle));
-	if (ACPI_FAILURE(status))
-		goto do_fail_zero;
-	status = acpi_get_handle(key->poll_hotkey.poll_handle,
-				 config_entry[bus_method], &tmp_handle);
-	if (ACPI_FAILURE(status))
-		goto do_fail_zero;
-	status =
-	    acpi_get_handle(NULL, config_entry[action_handle],
-			    &(key->poll_hotkey.action_handle));
-	if (ACPI_FAILURE(status))
-		goto do_fail_zero;
-	status = acpi_get_handle(key->poll_hotkey.action_handle,
-				 config_entry[method], &tmp_handle);
-	if (ACPI_FAILURE(status))
-		goto do_fail_zero;
-	key->poll_hotkey.poll_result =
-	    kmalloc(sizeof(union acpi_object), GFP_KERNEL);
-	if (!key->poll_hotkey.poll_result)
-		goto do_fail_zero;
-	return AE_OK;
-
-do_fail_zero:
-	key->poll_hotkey.poll_method = NULL;
-	key->poll_hotkey.action_method = NULL;
-do_fail:
-	return -ENODEV;
-}
-
-static int hotkey_open_config(struct inode *inode, struct file *file)
-{
-	return (single_open
-		     (file, hotkey_config_seq_show, PDE(inode)->data));
-}
-
-static int hotkey_poll_open_config(struct inode *inode, struct file *file)
-{
-	return (single_open
-		     (file, hotkey_poll_config_seq_show, PDE(inode)->data));
-}
-
-static int hotkey_config_seq_show(struct seq_file *seq, void *offset)
-{
-	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
-	struct list_head *entries;
-	char bus_name[ACPI_PATHNAME_MAX] = { 0 };
-	char action_name[ACPI_PATHNAME_MAX] = { 0 };
-	struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
-	struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };
-
-
-	list_for_each(entries, hotkey_list->entries) {
-		union acpi_hotkey *key =
-		    container_of(entries, union acpi_hotkey, entries);
-		if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
-			acpi_get_name(key->event_hotkey.bus_handle,
-				      ACPI_NAME_TYPE_MAX, &bus);
-			acpi_get_name(key->event_hotkey.action_handle,
-				      ACPI_NAME_TYPE_MAX, &act);
-			seq_printf(seq, "%s:%s:%s:%d:%d\n", bus_name,
-				   action_name,
-				   key->event_hotkey.action_method,
-				   key->link.hotkey_standard_num,
-				   key->event_hotkey.external_hotkey_num);
-		}
-	}
-	seq_puts(seq, "\n");
-	return 0;
-}
-
-static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset)
-{
-	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
-	struct list_head *entries;
-	char bus_name[ACPI_PATHNAME_MAX] = { 0 };
-	char action_name[ACPI_PATHNAME_MAX] = { 0 };
-	struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
-	struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };
-
-
-	list_for_each(entries, hotkey_list->entries) {
-		union acpi_hotkey *key =
-		    container_of(entries, union acpi_hotkey, entries);
-		if (key->link.hotkey_type == ACPI_HOTKEY_POLLING) {
-			acpi_get_name(key->poll_hotkey.poll_handle,
-				      ACPI_NAME_TYPE_MAX, &bus);
-			acpi_get_name(key->poll_hotkey.action_handle,
-				      ACPI_NAME_TYPE_MAX, &act);
-			seq_printf(seq, "%s:%s:%s:%s:%d\n", bus_name,
-				   key->poll_hotkey.poll_method,
-				   action_name,
-				   key->poll_hotkey.action_method,
-				   key->link.hotkey_standard_num);
-		}
-	}
-	seq_puts(seq, "\n");
-	return 0;
-}
-
-static int
-get_parms(char *config_record, int *cmd, char **config_entry,
-	       int *internal_event_num, int *external_event_num)
-{
-/* the format of *config_record =
- * "1:\d+:*" : "cmd:internal_event_num"
- * "\d+:\w+:\w+:\w+:\w+:\d+:\d+" :
- * "cmd:bus_handle:bus_method:action_handle:method:internal_event_num:external_event_num"
- */
-	char *tmp, *tmp1, count;
-	int i;
-
-	sscanf(config_record, "%d", cmd);
-	if (*cmd == 1) {
-		if (sscanf(config_record, "%d:%d", cmd, internal_event_num) !=
-		    2)
-			goto do_fail;
-		else
-			return (6);
-	}
-	tmp = strchr(config_record, ':');
-	if (!tmp)
-		goto do_fail;
-	tmp++;
-	for (i = 0; i < LAST_CONF_ENTRY; i++) {
-		tmp1 = strchr(tmp, ':');
-		if (!tmp1) {
-			goto do_fail;
-		}
-		count = tmp1 - tmp;
-		config_entry[i] = kzalloc(count + 1, GFP_KERNEL);
-		if (!config_entry[i])
-			goto handle_failure;
-		strncpy(config_entry[i], tmp, count);
-		tmp = tmp1 + 1;
-	}
-	if (sscanf(tmp, "%d:%d", internal_event_num, external_event_num) <= 0)
-		goto handle_failure;
-	if (!IS_OTHERS(*internal_event_num)) {
-		return 6;
-	}
-handle_failure:
-	while (i-- > 0)
-		kfree(config_entry[i]);
-do_fail:
-	return -1;
-}
-
-/*  count is length for one input record */
-static ssize_t hotkey_write_config(struct file *file,
-				   const char __user * buffer,
-				   size_t count, loff_t * data)
-{
-	char *config_record = NULL;
-	char *config_entry[LAST_CONF_ENTRY];
-	int cmd, internal_event_num, external_event_num;
-	int ret = 0;
-	union acpi_hotkey *key = kzalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
-
-	if (!key)
-		return -ENOMEM;
-
-	config_record = kzalloc(count + 1, GFP_KERNEL);
-	if (!config_record) {
-		kfree(key);
-		return -ENOMEM;
-	}
-
-	if (copy_from_user(config_record, buffer, count)) {
-		kfree(config_record);
-		kfree(key);
-		printk(KERN_ERR PREFIX "Invalid data\n");
-		return -EINVAL;
-	}
-	ret = get_parms(config_record, &cmd, config_entry,
-		       &internal_event_num, &external_event_num);
-	kfree(config_record);
-	if (ret != 6) {
-		printk(KERN_ERR PREFIX "Invalid data format ret=%d\n", ret);
-		return -EINVAL;
-	}
-
-	if (cmd == 1) {
-		union acpi_hotkey *tmp = NULL;
-		tmp = get_hotkey_by_event(&global_hotkey_list,
-					  internal_event_num);
-		if (!tmp)
-			printk(KERN_ERR PREFIX "Invalid key\n");
-		else
-			memcpy(key, tmp, sizeof(union acpi_hotkey));
-		goto cont_cmd;
-	}
-	if (IS_EVENT(internal_event_num)) {
-		if (init_hotkey_device(key, config_entry,
-			internal_event_num, external_event_num))
-			goto init_hotkey_fail;
-	} else {
-		if (init_poll_hotkey_device(key, config_entry,
-			       internal_event_num))
-			goto init_poll_hotkey_fail;
-	}
-cont_cmd:
-	switch (cmd) {
-	case 0:
-		if (get_hotkey_by_event(&global_hotkey_list,
-				key->link.hotkey_standard_num))
-			goto fail_out;
-		else
-			hotkey_add(key);
-		break;
-	case 1:
-		hotkey_remove(key);
-		break;
-	case 2:
-		/* key is kfree()ed if matched*/
-		if (hotkey_update(key))
-			goto fail_out;
-		break;
-	default:
-		goto fail_out;
-		break;
-	}
-	return count;
-
-init_poll_hotkey_fail:		/* failed init_poll_hotkey_device */
-	kfree(config_entry[bus_method]);
-	config_entry[bus_method] = NULL;
-init_hotkey_fail:		/* failed init_hotkey_device */
-	kfree(config_entry[method]);
-fail_out:
-	kfree(config_entry[bus_handle]);
-	kfree(config_entry[action_handle]);
-	/* No double free since elements =NULL for error cases */
-	if (IS_EVENT(internal_event_num)) {
-		if (config_entry[bus_method])
-			kfree(config_entry[bus_method]);
-		free_hotkey_buffer(key);	/* frees [method] */
-	} else
-		free_poll_hotkey_buffer(key);  /* frees [bus_method]+[method] */
-	kfree(key);
-	printk(KERN_ERR PREFIX "invalid key\n");
-	return -EINVAL;
-}
-
-/*
- * This function evaluates an ACPI method, given an int as parameter, the
- * method is searched within the scope of the handle, can be NULL. The output
- * of the method is written is output, which can also be NULL
- *
- * returns 1 if write is successful, 0 else.
- */
-static int write_acpi_int(acpi_handle handle, const char *method, int val,
-			  struct acpi_buffer *output)
-{
-	struct acpi_object_list params;	/* list of input parameters (an int here) */
-	union acpi_object in_obj;	/* the only param we use */
-	acpi_status status;
-
-	params.count = 1;
-	params.pointer = &in_obj;
-	in_obj.type = ACPI_TYPE_INTEGER;
-	in_obj.integer.value = val;
-
-	status = acpi_evaluate_object(handle, (char *)method, &params, output);
-
-	return (status == AE_OK);
-}
-
-static int read_acpi_int(acpi_handle handle, const char *method,
-			 union acpi_object *val)
-{
-	struct acpi_buffer output;
-	union acpi_object out_obj;
-	acpi_status status;
-
-	output.length = sizeof(out_obj);
-	output.pointer = &out_obj;
-
-	status = acpi_evaluate_object(handle, (char *)method, NULL, &output);
-	if (val) {
-		val->integer.value = out_obj.integer.value;
-		val->type = out_obj.type;
-	} else
-		printk(KERN_ERR PREFIX "null val pointer\n");
-	return ((status == AE_OK)
-		     && (out_obj.type == ACPI_TYPE_INTEGER));
-}
-
-static union acpi_hotkey *get_hotkey_by_event(struct
-					      acpi_hotkey_list
-					      *hotkey_list, int event)
-{
-	struct list_head *entries;
-
-	list_for_each(entries, hotkey_list->entries) {
-		union acpi_hotkey *key =
-		    container_of(entries, union acpi_hotkey, entries);
-		if (key->link.hotkey_standard_num == event) {
-			return (key);
-		}
-	}
-	return (NULL);
-}
-
-/*
- * user call AML method interface:
- * Call convention:
- * echo "event_num: arg type : value"
- * example: echo "1:1:30" > /proc/acpi/action
- * Just support 1 integer arg passing to AML method
- */
-
-static ssize_t hotkey_execute_aml_method(struct file *file,
-					 const char __user * buffer,
-					 size_t count, loff_t * data)
-{
-	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
-	char *arg;
-	int event, method_type, type, value;
-	union acpi_hotkey *key;
-
-
-	arg = kzalloc(count + 1, GFP_KERNEL);
-	if (!arg)
-		return -ENOMEM;
-
-	if (copy_from_user(arg, buffer, count)) {
-		kfree(arg);
-		printk(KERN_ERR PREFIX "Invalid argument 2\n");
-		return -EINVAL;
-	}
-
-	if (sscanf(arg, "%d:%d:%d:%d", &event, &method_type, &type, &value) !=
-	    4) {
-		kfree(arg);
-		printk(KERN_ERR PREFIX "Invalid argument 3\n");
-		return -EINVAL;
-	}
-	kfree(arg);
-	if (type == ACPI_TYPE_INTEGER) {
-		key = get_hotkey_by_event(hotkey_list, event);
-		if (!key)
-			goto do_fail;
-		if (IS_EVENT(event))
-			write_acpi_int(key->event_hotkey.action_handle,
-				       key->event_hotkey.action_method, value,
-				       NULL);
-		else if (IS_POLL(event)) {
-			if (method_type == POLL_METHOD)
-				read_acpi_int(key->poll_hotkey.poll_handle,
-					      key->poll_hotkey.poll_method,
-					      key->poll_hotkey.poll_result);
-			else if (method_type == ACTION_METHOD)
-				write_acpi_int(key->poll_hotkey.action_handle,
-					       key->poll_hotkey.action_method,
-					       value, NULL);
-			else
-				goto do_fail;
-
-		}
-	} else {
-		printk(KERN_WARNING "Not supported\n");
-		return -EINVAL;
-	}
-	return count;
-      do_fail:
-	return -EINVAL;
-
-}
-
-static int __init hotkey_init(void)
-{
-	int result;
-	mode_t mode = S_IFREG | S_IRUGO | S_IWUGO;
-
-
-	if (acpi_disabled)
-		return -ENODEV;
-
-	if (acpi_specific_hotkey_enabled) {
-		printk("Using specific hotkey driver\n");
-		return -ENODEV;
-	}
-
-	hotkey_proc_dir = proc_mkdir(HOTKEY_PROC, acpi_root_dir);
-	if (!hotkey_proc_dir) {
-		return (-ENODEV);
-	}
-	hotkey_proc_dir->owner = THIS_MODULE;
-
-	hotkey_config =
-	    create_proc_entry(HOTKEY_EV_CONFIG, mode, hotkey_proc_dir);
-	if (!hotkey_config) {
-		goto do_fail1;
-	} else {
-		hotkey_config->proc_fops = &hotkey_config_fops;
-		hotkey_config->data = &global_hotkey_list;
-		hotkey_config->owner = THIS_MODULE;
-		hotkey_config->uid = 0;
-		hotkey_config->gid = 0;
-	}
-
-	hotkey_poll_config =
-	    create_proc_entry(HOTKEY_PL_CONFIG, mode, hotkey_proc_dir);
-	if (!hotkey_poll_config) {
-		goto do_fail2;
-	} else {
-		hotkey_poll_config->proc_fops = &hotkey_poll_config_fops;
-		hotkey_poll_config->data = &global_hotkey_list;
-		hotkey_poll_config->owner = THIS_MODULE;
-		hotkey_poll_config->uid = 0;
-		hotkey_poll_config->gid = 0;
-	}
-
-	hotkey_action = create_proc_entry(HOTKEY_ACTION, mode, hotkey_proc_dir);
-	if (!hotkey_action) {
-		goto do_fail3;
-	} else {
-		hotkey_action->proc_fops = &hotkey_action_fops;
-		hotkey_action->owner = THIS_MODULE;
-		hotkey_action->uid = 0;
-		hotkey_action->gid = 0;
-	}
-
-	hotkey_info = create_proc_entry(HOTKEY_INFO, mode, hotkey_proc_dir);
-	if (!hotkey_info) {
-		goto do_fail4;
-	} else {
-		hotkey_info->proc_fops = &hotkey_info_fops;
-		hotkey_info->owner = THIS_MODULE;
-		hotkey_info->uid = 0;
-		hotkey_info->gid = 0;
-	}
-
-	result = acpi_bus_register_driver(&hotkey_driver);
-	if (result < 0)
-		goto do_fail5;
-	global_hotkey_list.count = 0;
-	global_hotkey_list.entries = &hotkey_entries;
-
-	INIT_LIST_HEAD(&hotkey_entries);
-
-	return (0);
-
-      do_fail5:
-	remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
-      do_fail4:
-	remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
-      do_fail3:
-	remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
-      do_fail2:
-	remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
-      do_fail1:
-	remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
-	return (-ENODEV);
-}
-
-static void __exit hotkey_exit(void)
-{
-	struct list_head *entries, *next;
-
-
-	list_for_each_safe(entries, next, global_hotkey_list.entries) {
-		union acpi_hotkey *key =
-		    container_of(entries, union acpi_hotkey, entries);
-
-		acpi_os_wait_events_complete(NULL);
-		list_del(&key->link.entries);
-		global_hotkey_list.count--;
-		free_hotkey_device(key);
-	}
-	acpi_bus_unregister_driver(&hotkey_driver);
-	remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
-	remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
-	remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
-	remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
-	remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
-	return;
-}
-
-module_init(hotkey_init);
-module_exit(hotkey_exit);
diff --git a/drivers/acpi/i2c_ec.c b/drivers/acpi/i2c_ec.c
index 76ec8b6..acab4a4 100644
--- a/drivers/acpi/i2c_ec.c
+++ b/drivers/acpi/i2c_ec.c
@@ -27,18 +27,17 @@
 #define ACPI_EC_HC_COMPONENT	0x00080000
 #define ACPI_EC_HC_CLASS	"ec_hc_smbus"
 #define ACPI_EC_HC_HID		"ACPI0001"
-#define ACPI_EC_HC_DRIVER_NAME	"ACPI EC HC smbus driver"
 #define ACPI_EC_HC_DEVICE_NAME	"EC HC smbus"
 
 #define _COMPONENT		ACPI_EC_HC_COMPONENT
 
-ACPI_MODULE_NAME("acpi_smbus")
+ACPI_MODULE_NAME("i2c_ec");
 
 static int acpi_ec_hc_add(struct acpi_device *device);
 static int acpi_ec_hc_remove(struct acpi_device *device, int type);
 
 static struct acpi_driver acpi_ec_hc_driver = {
-	.name = ACPI_EC_HC_DRIVER_NAME,
+	.name = "i2c_ec",
 	.class = ACPI_EC_HC_CLASS,
 	.ids = ACPI_EC_HC_HID,
 	.ops = {
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index c6144ca..1a0ed3d 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -496,6 +496,10 @@
 	printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
 	printk(IBM_INFO "%s\n", IBM_URL);
 
+	if (ibm_thinkpad_ec_found)
+		printk(IBM_INFO "ThinkPad EC firmware %s\n",
+		       ibm_thinkpad_ec_found);
+
 	return 0;
 }
 
@@ -2617,7 +2621,7 @@
 	ibm_handle_init(#object, &object##_handle, *object##_parent,	\
 		object##_paths, ARRAY_SIZE(object##_paths), &object##_path)
 
-static int set_ibm_param(const char *val, struct kernel_param *kp)
+static int __init set_ibm_param(const char *val, struct kernel_param *kp)
 {
 	unsigned int i;
 
@@ -2659,7 +2663,8 @@
 	for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--)
 		ibm_exit(&ibms[i]);
 
-	remove_proc_entry(IBM_DIR, acpi_root_dir);
+	if (proc_dir)
+		remove_proc_entry(IBM_DIR, acpi_root_dir);
 
 	if (ibm_thinkpad_ec_found)
 		kfree(ibm_thinkpad_ec_found);
@@ -2696,11 +2701,6 @@
 	if (acpi_disabled)
 		return -ENODEV;
 
-	if (!acpi_specific_hotkey_enabled) {
-		printk(IBM_ERR "using generic hotkey driver\n");
-		return -ENODEV;
-	}
-
 	/* ec is required because many other handles are relative to it */
 	IBM_HANDLE_INIT(ec);
 	if (!ec_handle) {
@@ -2710,9 +2710,6 @@
 
 	/* Models with newer firmware report the EC in DMI */
 	ibm_thinkpad_ec_found = check_dmi_for_ec();
-	if (ibm_thinkpad_ec_found)
-		printk(IBM_INFO "ThinkPad EC firmware %s\n",
-		       ibm_thinkpad_ec_found);
 
 	/* these handles are not required */
 	IBM_HANDLE_INIT(vid);
@@ -2742,6 +2739,7 @@
 	proc_dir = proc_mkdir(IBM_DIR, acpi_root_dir);
 	if (!proc_dir) {
 		printk(IBM_ERR "unable to create proc dir %s", IBM_DIR);
+		acpi_ibm_exit();
 		return -ENODEV;
 	}
 	proc_dir->owner = THIS_MODULE;
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 4a9faff..8fcd6a1 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -33,7 +33,7 @@
 
 #define ACPI_NUMA	0x80000000
 #define _COMPONENT	ACPI_NUMA
-ACPI_MODULE_NAME("numa")
+ACPI_MODULE_NAME("numa");
 
 static nodemask_t nodes_found_map = NODE_MASK_NONE;
 #define PXM_INVAL	-1
@@ -45,12 +45,6 @@
 int __cpuinitdata node_to_pxm_map[MAX_NUMNODES]
 				= { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
 
-extern int __init acpi_table_parse_madt_family(char *id,
-					       unsigned long madt_size,
-					       int entry_id,
-					       acpi_madt_entry_handler handler,
-					       unsigned int max_entries);
-
 int __cpuinit pxm_to_node(int pxm)
 {
 	if (pxm < 0)
@@ -208,9 +202,9 @@
 
 int __init
 acpi_table_parse_srat(enum acpi_srat_type id,
-		      acpi_madt_entry_handler handler, unsigned int max_entries)
+		      acpi_table_entry_handler handler, unsigned int max_entries)
 {
-	return acpi_table_parse_madt_family(ACPI_SIG_SRAT,
+	return acpi_table_parse_entries(ACPI_SIG_SRAT,
 					    sizeof(struct acpi_table_srat), id,
 					    handler, max_entries);
 }
@@ -220,9 +214,7 @@
 	int result;
 
 	/* SRAT: Static Resource Affinity Table */
-	result = acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat);
-
-	if (result > 0) {
+	if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
 		result = acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
 					       acpi_parse_processor_affinity,
 					       NR_CPUS);
@@ -230,7 +222,7 @@
 	}
 
 	/* SLIT: System Locality Information Table */
-	result = acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
+	acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
 
 	acpi_numa_arch_fixup();
 	return 0;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 0f6f3bc..971eca4 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -46,7 +46,7 @@
 #include <linux/efi.h>
 
 #define _COMPONENT		ACPI_OS_SERVICES
-ACPI_MODULE_NAME("osl")
+ACPI_MODULE_NAME("osl");
 #define PREFIX		"ACPI: "
 struct acpi_os_dpc {
 	acpi_osd_exec_callback function;
@@ -68,9 +68,6 @@
 extern char line_buf[80];
 #endif				/*ENABLE_DEBUGGER */
 
-int acpi_specific_hotkey_enabled = TRUE;
-EXPORT_SYMBOL(acpi_specific_hotkey_enabled);
-
 static unsigned int acpi_irq_irq;
 static acpi_osd_handler acpi_irq_handler;
 static void *acpi_irq_context;
@@ -205,7 +202,7 @@
 {
 	if (phys > ULONG_MAX) {
 		printk(KERN_ERR PREFIX "Cannot map memory that high\n");
-		return 0;
+		return NULL;
 	}
 	if (acpi_gbl_permanent_mmap)
 		/*
@@ -890,26 +887,6 @@
 }
 #endif				/*  ACPI_FUTURE_USAGE  */
 
-/* Assumes no unreadable holes inbetween */
-u8 acpi_os_readable(void *ptr, acpi_size len)
-{
-#if defined(__i386__) || defined(__x86_64__)
-	char tmp;
-	return !__get_user(tmp, (char __user *)ptr)
-	    && !__get_user(tmp, (char __user *)ptr + len - 1);
-#endif
-	return 1;
-}
-
-#ifdef ACPI_FUTURE_USAGE
-u8 acpi_os_writable(void *ptr, acpi_size len)
-{
-	/* could do dummy write (racy) or a kernel page table lookup.
-	   The later may be difficult at early boot when kmap doesn't work yet. */
-	return 1;
-}
-#endif
-
 acpi_status acpi_os_signal(u32 function, void *info)
 {
 	switch (function) {
@@ -1012,14 +989,6 @@
 
 __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
 
-static int __init acpi_hotkey_setup(char *str)
-{
-	acpi_specific_hotkey_enabled = FALSE;
-	return 1;
-}
-
-__setup("acpi_generic_hotkey", acpi_hotkey_setup);
-
 /*
  * max_cstate is defined in the base kernel so modules can
  * change it w/o depending on the state of the processor module.
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
index 55f57a6..0289693 100644
--- a/drivers/acpi/pci_bind.c
+++ b/drivers/acpi/pci_bind.c
@@ -36,7 +36,7 @@
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT		ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME("pci_bind")
+ACPI_MODULE_NAME("pci_bind");
 
 struct acpi_pci_data {
 	struct acpi_pci_id id;
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index fe7d007..dd3186a 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -38,7 +38,7 @@
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT		ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME("pci_irq")
+ACPI_MODULE_NAME("pci_irq");
 
 static struct acpi_prt_list acpi_prt;
 static DEFINE_SPINLOCK(acpi_prt_lock);
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 0f683c8..acc5947 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -44,10 +44,9 @@
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT		ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME("pci_link")
+ACPI_MODULE_NAME("pci_link");
 #define ACPI_PCI_LINK_CLASS		"pci_irq_routing"
 #define ACPI_PCI_LINK_HID		"PNP0C0F"
-#define ACPI_PCI_LINK_DRIVER_NAME	"ACPI PCI Interrupt Link Driver"
 #define ACPI_PCI_LINK_DEVICE_NAME	"PCI Interrupt Link"
 #define ACPI_PCI_LINK_FILE_INFO		"info"
 #define ACPI_PCI_LINK_FILE_STATUS	"state"
@@ -56,7 +55,7 @@
 static int acpi_pci_link_remove(struct acpi_device *device, int type);
 
 static struct acpi_driver acpi_pci_link_driver = {
-	.name = ACPI_PCI_LINK_DRIVER_NAME,
+	.name = "pci_link",
 	.class = ACPI_PCI_LINK_CLASS,
 	.ids = ACPI_PCI_LINK_HID,
 	.ops = {
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 4ecf701..ad4145a 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -36,17 +36,16 @@
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT		ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME("pci_root")
+ACPI_MODULE_NAME("pci_root");
 #define ACPI_PCI_ROOT_CLASS		"pci_bridge"
 #define ACPI_PCI_ROOT_HID		"PNP0A03"
-#define ACPI_PCI_ROOT_DRIVER_NAME	"ACPI PCI Root Bridge Driver"
 #define ACPI_PCI_ROOT_DEVICE_NAME	"PCI Root Bridge"
 static int acpi_pci_root_add(struct acpi_device *device);
 static int acpi_pci_root_remove(struct acpi_device *device, int type);
 static int acpi_pci_root_start(struct acpi_device *device);
 
 static struct acpi_driver acpi_pci_root_driver = {
-	.name = ACPI_PCI_ROOT_DRIVER_NAME,
+	.name = "pci_root",
 	.class = ACPI_PCI_ROOT_CLASS,
 	.ids = ACPI_PCI_ROOT_HID,
 	.ops = {
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 0ba7dfb..1ef3385 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -45,10 +45,9 @@
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT		ACPI_POWER_COMPONENT
-ACPI_MODULE_NAME("acpi_power")
+ACPI_MODULE_NAME("power");
 #define ACPI_POWER_COMPONENT		0x00800000
 #define ACPI_POWER_CLASS		"power_resource"
-#define ACPI_POWER_DRIVER_NAME		"ACPI Power Resource Driver"
 #define ACPI_POWER_DEVICE_NAME		"Power Resource"
 #define ACPI_POWER_FILE_INFO		"info"
 #define ACPI_POWER_FILE_STATUS		"state"
@@ -57,25 +56,33 @@
 #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
 static int acpi_power_add(struct acpi_device *device);
 static int acpi_power_remove(struct acpi_device *device, int type);
+static int acpi_power_resume(struct acpi_device *device);
 static int acpi_power_open_fs(struct inode *inode, struct file *file);
 
 static struct acpi_driver acpi_power_driver = {
-	.name = ACPI_POWER_DRIVER_NAME,
+	.name = "power",
 	.class = ACPI_POWER_CLASS,
 	.ids = ACPI_POWER_HID,
 	.ops = {
 		.add = acpi_power_add,
 		.remove = acpi_power_remove,
+		.resume = acpi_power_resume,
 		},
 };
 
+struct acpi_power_reference {
+	struct list_head node;
+	struct acpi_device *device;
+};
+
 struct acpi_power_resource {
 	struct acpi_device * device;
 	acpi_bus_id name;
 	u32 system_level;
 	u32 order;
 	int state;
-	int references;
+	struct mutex resource_lock;
+	struct list_head reference;
 };
 
 static struct list_head acpi_power_resource_list;
@@ -171,22 +178,47 @@
 	return result;
 }
 
-static int acpi_power_on(acpi_handle handle)
+static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
 {
 	int result = 0;
+	int found = 0;
 	acpi_status status = AE_OK;
-	struct acpi_device *device = NULL;
 	struct acpi_power_resource *resource = NULL;
+	struct list_head *node, *next;
+	struct acpi_power_reference *ref;
 
 
 	result = acpi_power_get_context(handle, &resource);
 	if (result)
 		return result;
 
-	resource->references++;
+	mutex_lock(&resource->resource_lock);
+	list_for_each_safe(node, next, &resource->reference) {
+		ref = container_of(node, struct acpi_power_reference, node);
+		if (dev->handle == ref->device->handle) {
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] already referenced by resource [%s]\n",
+				  dev->pnp.bus_id, resource->name));
+			found = 1;
+			break;
+		}
+	}
 
-	if ((resource->references > 1)
-	    || (resource->state == ACPI_POWER_RESOURCE_STATE_ON)) {
+	if (!found) {
+		ref = kmalloc(sizeof (struct acpi_power_reference),
+		    irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
+		if (!ref) {
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "kmalloc() failed\n"));
+			mutex_unlock(&resource->resource_lock);
+			return -ENOMEM;
+		}
+		list_add_tail(&ref->node, &resource->reference);
+		ref->device = dev;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] added to resource [%s] references\n",
+			  dev->pnp.bus_id, resource->name));
+	}
+	mutex_unlock(&resource->resource_lock);
+
+	if (resource->state == ACPI_POWER_RESOURCE_STATE_ON) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already on\n",
 				  resource->name));
 		return 0;
@@ -203,38 +235,49 @@
 		return -ENOEXEC;
 
 	/* Update the power resource's _device_ power state */
-	device = resource->device;
 	resource->device->power.state = ACPI_STATE_D0;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n",
 			  resource->name));
-
 	return 0;
 }
 
-static int acpi_power_off_device(acpi_handle handle)
+static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
 {
 	int result = 0;
 	acpi_status status = AE_OK;
 	struct acpi_power_resource *resource = NULL;
+	struct list_head *node, *next;
+	struct acpi_power_reference *ref;
+
 
 	result = acpi_power_get_context(handle, &resource);
 	if (result)
 		return result;
 
-	if (resource->references)
-		resource->references--;
+	mutex_lock(&resource->resource_lock);
+	list_for_each_safe(node, next, &resource->reference) {
+		ref = container_of(node, struct acpi_power_reference, node);
+		if (dev->handle == ref->device->handle) {
+			list_del(&ref->node);
+			kfree(ref);
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] removed from resource [%s] references\n",
+			    dev->pnp.bus_id, resource->name));
+			break;
+		}
+	}
 
-	if (resource->references) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Resource [%s] is still in use, dereferencing\n",
-				  resource->device->pnp.bus_id));
+	if (!list_empty(&resource->reference)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cannot turn resource [%s] off - resource is in use\n",
+		    resource->name));
+		mutex_unlock(&resource->resource_lock);
 		return 0;
 	}
+	mutex_unlock(&resource->resource_lock);
 
 	if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n",
-				  resource->device->pnp.bus_id));
+				  resource->name));
 		return 0;
 	}
 
@@ -276,7 +319,7 @@
 	arg.integer.value = 1;
 	/* Open power resource */
 	for (i = 0; i < dev->wakeup.resources.count; i++) {
-		ret = acpi_power_on(dev->wakeup.resources.handles[i]);
+		ret = acpi_power_on(dev->wakeup.resources.handles[i], dev);
 		if (ret) {
 			printk(KERN_ERR PREFIX "Transition power state\n");
 			dev->wakeup.flags.valid = 0;
@@ -323,7 +366,7 @@
 
 	/* Close power resource */
 	for (i = 0; i < dev->wakeup.resources.count; i++) {
-		ret = acpi_power_off_device(dev->wakeup.resources.handles[i]);
+		ret = acpi_power_off_device(dev->wakeup.resources.handles[i], dev);
 		if (ret) {
 			printk(KERN_ERR PREFIX "Transition power state\n");
 			dev->wakeup.flags.valid = 0;
@@ -407,16 +450,20 @@
 	 * (e.g. so the device doesn't lose power while transitioning).
 	 */
 	for (i = 0; i < tl->count; i++) {
-		result = acpi_power_on(tl->handles[i]);
+		result = acpi_power_on(tl->handles[i], device);
 		if (result)
 			goto end;
 	}
 
+	if (device->power.state == state) {
+		goto end;
+	}
+
 	/*
 	 * Then we dereference all power resources used in the current list.
 	 */
 	for (i = 0; i < cl->count; i++) {
-		result = acpi_power_off_device(cl->handles[i]);
+		result = acpi_power_off_device(cl->handles[i], device);
 		if (result)
 			goto end;
 	}
@@ -439,7 +486,11 @@
 
 static int acpi_power_seq_show(struct seq_file *seq, void *offset)
 {
+	int count = 0;
+	int result = 0;
 	struct acpi_power_resource *resource = NULL;
+	struct list_head *node, *next;
+	struct acpi_power_reference *ref;
 
 
 	resource = seq->private;
@@ -447,6 +498,10 @@
 	if (!resource)
 		goto end;
 
+	result = acpi_power_get_state(resource);
+	if (result)
+		goto end;
+
 	seq_puts(seq, "state:                   ");
 	switch (resource->state) {
 	case ACPI_POWER_RESOURCE_STATE_ON:
@@ -460,11 +515,18 @@
 		break;
 	}
 
+	mutex_lock(&resource->resource_lock);
+	list_for_each_safe(node, next, &resource->reference) {
+		ref = container_of(node, struct acpi_power_reference, node);
+		count++;
+	}
+	mutex_unlock(&resource->resource_lock);
+
 	seq_printf(seq, "system level:            S%d\n"
 		   "order:                   %d\n"
 		   "reference count:         %d\n",
 		   resource->system_level,
-		   resource->order, resource->references);
+		   resource->order, count);
 
       end:
 	return 0;
@@ -537,6 +599,8 @@
 		return -ENOMEM;
 
 	resource->device = device;
+	mutex_init(&resource->resource_lock);
+	INIT_LIST_HEAD(&resource->reference);
 	strcpy(resource->name, device->pnp.bus_id);
 	strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
@@ -584,6 +648,7 @@
 static int acpi_power_remove(struct acpi_device *device, int type)
 {
 	struct acpi_power_resource *resource = NULL;
+	struct list_head *node, *next;
 
 
 	if (!device || !acpi_driver_data(device))
@@ -593,11 +658,54 @@
 
 	acpi_power_remove_fs(device);
 
+	mutex_lock(&resource->resource_lock);
+	list_for_each_safe(node, next, &resource->reference) {
+		struct acpi_power_reference *ref = container_of(node, struct acpi_power_reference, node);
+		list_del(&ref->node);
+		kfree(ref);
+	}
+	mutex_unlock(&resource->resource_lock);
+
 	kfree(resource);
 
 	return 0;
 }
 
+static int acpi_power_resume(struct acpi_device *device)
+{
+	int result = 0;
+	struct acpi_power_resource *resource = NULL;
+	struct acpi_power_reference *ref;
+
+	if (!device || !acpi_driver_data(device))
+		return -EINVAL;
+
+	resource = (struct acpi_power_resource *)acpi_driver_data(device);
+
+	result = acpi_power_get_state(resource);
+	if (result)
+		return result;
+
+	mutex_lock(&resource->resource_lock);
+	if ((resource->state == ACPI_POWER_RESOURCE_STATE_ON) &&
+	    list_empty(&resource->reference)) {
+		mutex_unlock(&resource->resource_lock);
+		result = acpi_power_off_device(device->handle, NULL);
+		return result;
+	}
+
+	if ((resource->state == ACPI_POWER_RESOURCE_STATE_OFF) &&
+	    !list_empty(&resource->reference)) {
+		ref = container_of(resource->reference.next, struct acpi_power_reference, node);
+		mutex_unlock(&resource->resource_lock);
+		result = acpi_power_on(device->handle, ref->device);
+		return result;
+	}
+
+	mutex_unlock(&resource->resource_lock);
+	return 0;
+}
+
 static int __init acpi_power_init(void)
 {
 	int result = 0;
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 0079bc5..99d1516 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -60,7 +60,6 @@
 
 #define ACPI_PROCESSOR_COMPONENT	0x01000000
 #define ACPI_PROCESSOR_CLASS		"processor"
-#define ACPI_PROCESSOR_DRIVER_NAME	"ACPI Processor Driver"
 #define ACPI_PROCESSOR_DEVICE_NAME	"Processor"
 #define ACPI_PROCESSOR_FILE_INFO	"info"
 #define ACPI_PROCESSOR_FILE_THROTTLING	"throttling"
@@ -74,10 +73,10 @@
 #define ACPI_STA_PRESENT 0x00000001
 
 #define _COMPONENT		ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME("acpi_processor")
+ACPI_MODULE_NAME("processor_core");
 
-    MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME);
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION("ACPI Processor Driver");
 MODULE_LICENSE("GPL");
 
 static int acpi_processor_add(struct acpi_device *device);
@@ -89,7 +88,7 @@
 static int acpi_processor_handle_eject(struct acpi_processor *pr);
 
 static struct acpi_driver acpi_processor_driver = {
-	.name = ACPI_PROCESSOR_DRIVER_NAME,
+	.name = "processor",
 	.class = ACPI_PROCESSOR_CLASS,
 	.ids = ACPI_PROCESSOR_HID,
 	.ops = {
@@ -404,7 +403,7 @@
 	if (lsapic->lapic_flags & ACPI_MADT_ENABLED) {
 		/* First check against id */
 		if (lsapic->processor_id == acpi_id) {
-			*apic_id = lsapic->id;
+			*apic_id = (lsapic->id << 8) | lsapic->eid;
 			return 1;
 		/* Check against optional uid */
 		} else if (entry->length >= 16 &&
@@ -1005,7 +1004,7 @@
 #ifdef CONFIG_SMP
 	if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
 				(struct acpi_table_header **)&madt)))
-		madt = 0;
+		madt = NULL;
 #endif
 
 	acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 8206fc1..6077300 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -51,6 +51,14 @@
 #include <asm/apic.h>
 #endif
 
+/*
+ * Include the apic definitions for x86 to have the APIC timer related defines
+ * available also for UP (on SMP it gets magically included via linux/smp.h).
+ */
+#ifdef CONFIG_X86
+#include <asm/apic.h>
+#endif
+
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
@@ -59,9 +67,8 @@
 
 #define ACPI_PROCESSOR_COMPONENT        0x01000000
 #define ACPI_PROCESSOR_CLASS            "processor"
-#define ACPI_PROCESSOR_DRIVER_NAME      "ACPI Processor Driver"
 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME("acpi_processor")
+ACPI_MODULE_NAME("processor_idle");
 #define ACPI_PROCESSOR_FILE_POWER	"power"
 #define US_TO_PM_TIMER_TICKS(t)		((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
 #define C2_OVERHEAD			4	/* 1us (3.579 ticks per us) */
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 058f13c..2f2e796 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -44,10 +44,9 @@
 
 #define ACPI_PROCESSOR_COMPONENT	0x01000000
 #define ACPI_PROCESSOR_CLASS		"processor"
-#define ACPI_PROCESSOR_DRIVER_NAME	"ACPI Processor Driver"
 #define ACPI_PROCESSOR_FILE_PERFORMANCE	"performance"
 #define _COMPONENT		ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME("acpi_processor")
+ACPI_MODULE_NAME("processor_perflib");
 
 static DEFINE_MUTEX(performance_mutex);
 
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 40fecd6..06e6f3f 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -41,9 +41,8 @@
 
 #define ACPI_PROCESSOR_COMPONENT        0x01000000
 #define ACPI_PROCESSOR_CLASS            "processor"
-#define ACPI_PROCESSOR_DRIVER_NAME      "ACPI Processor Driver"
 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME("acpi_processor")
+ACPI_MODULE_NAME("processor_thermal");
 
 /* --------------------------------------------------------------------------
                                  Limit Interface
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 89dff36..b334860 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -41,9 +41,8 @@
 
 #define ACPI_PROCESSOR_COMPONENT        0x01000000
 #define ACPI_PROCESSOR_CLASS            "processor"
-#define ACPI_PROCESSOR_DRIVER_NAME      "ACPI Processor Driver"
 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME("acpi_processor")
+ACPI_MODULE_NAME("processor_throttling");
 
 /* --------------------------------------------------------------------------
                               Throttling Control
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index f58fc74..59640d9 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -59,7 +59,6 @@
 #define ACPI_AC_CLASS			"ac_adapter"
 #define ACPI_BATTERY_CLASS		"battery"
 #define ACPI_SBS_HID			"ACPI0002"
-#define ACPI_SBS_DRIVER_NAME		"ACPI Smart Battery System Driver"
 #define ACPI_SBS_DEVICE_NAME		"Smart Battery System"
 #define ACPI_SBS_FILE_INFO		"info"
 #define ACPI_SBS_FILE_STATE		"state"
@@ -78,7 +77,7 @@
 #define	MAX_SBS_BAT			4
 #define	MAX_SMBUS_ERR			1
 
-ACPI_MODULE_NAME("acpi_sbs");
+ACPI_MODULE_NAME("sbs");
 
 MODULE_AUTHOR("Rich Townsend");
 MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
@@ -110,7 +109,7 @@
 static void acpi_sbs_update_queue(void *data);
 
 static struct acpi_driver acpi_sbs_driver = {
-	.name = ACPI_SBS_DRIVER_NAME,
+	.name = "sbs",
 	.class = ACPI_SBS_CLASS,
 	.ids = ACPI_SBS_HID,
 	.ops = {
@@ -1034,21 +1033,19 @@
 	} else {
 		seq_printf(seq, "capacity state:          ok\n");
 	}
+
+	foo = (s16) battery->state.amperage * battery->info.ipscale;
+	if (battery->info.capacity_mode) {
+		foo = foo * battery->info.design_voltage / 1000;
+	}
 	if (battery->state.amperage < 0) {
 		seq_printf(seq, "charging state:          discharging\n");
-		foo = battery->state.remaining_capacity * cscale * 60 /
-		    (battery->state.average_time_to_empty == 0 ? 1 :
-		     battery->state.average_time_to_empty);
-		seq_printf(seq, "present rate:            %i%s\n",
-			   foo, battery->info.capacity_mode ? "0 mW" : " mA");
+		seq_printf(seq, "present rate:            %d %s\n",
+			   -foo, battery->info.capacity_mode ? "mW" : "mA");
 	} else if (battery->state.amperage > 0) {
 		seq_printf(seq, "charging state:          charging\n");
-		foo = (battery->info.full_charge_capacity -
-		       battery->state.remaining_capacity) * cscale * 60 /
-		    (battery->state.average_time_to_full == 0 ? 1 :
-		     battery->state.average_time_to_full);
-		seq_printf(seq, "present rate:            %i%s\n",
-			   foo, battery->info.capacity_mode ? "0 mW" : " mA");
+		seq_printf(seq, "present rate:            %d %s\n",
+			   foo, battery->info.capacity_mode ? "mW" : "mA");
 	} else {
 		seq_printf(seq, "charging state:          charged\n");
 		seq_printf(seq, "present rate:            0 %s\n",
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 64f26db..bb0e0da 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -11,13 +11,12 @@
 #include <acpi/acinterp.h>	/* for acpi_ex_eisa_id_to_string() */
 
 #define _COMPONENT		ACPI_BUS_COMPONENT
-ACPI_MODULE_NAME("scan")
+ACPI_MODULE_NAME("scan");
 #define STRUCT_TO_INT(s)	(*((int*)&s))
 extern struct acpi_device *acpi_root;
 
 #define ACPI_BUS_CLASS			"system_bus"
 #define ACPI_BUS_HID			"ACPI_BUS"
-#define ACPI_BUS_DRIVER_NAME		"ACPI Bus Driver"
 #define ACPI_BUS_DEVICE_NAME		"System Bus"
 
 static LIST_HEAD(acpi_device_list);
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 62ce87d..37a0930 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -200,7 +200,7 @@
 	{},
 };
 
-static int __init acpi_sleep_init(void)
+int __init acpi_sleep_init(void)
 {
 	int i = 0;
 
@@ -229,4 +229,3 @@
 	return 0;
 }
 
-late_initcall(acpi_sleep_init);
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 7147b0b..83a8d30 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -31,14 +31,13 @@
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
-ACPI_MODULE_NAME("acpi_system")
+ACPI_MODULE_NAME("system");
 #ifdef MODULE_PARAM_PREFIX
 #undef MODULE_PARAM_PREFIX
 #endif
 #define MODULE_PARAM_PREFIX "acpi."
 
 #define ACPI_SYSTEM_CLASS		"system"
-#define ACPI_SYSTEM_DRIVER_NAME		"ACPI System Driver"
 #define ACPI_SYSTEM_DEVICE_NAME		"System"
 #define ACPI_SYSTEM_FILE_INFO		"info"
 #define ACPI_SYSTEM_FILE_EVENT		"event"
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 45bd173..849e2c3 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -169,40 +169,40 @@
 
 
 int __init
-acpi_table_parse_madt_family(char *id,
-			     unsigned long madt_size,
+acpi_table_parse_entries(char *id,
+			     unsigned long table_size,
 			     int entry_id,
-			     acpi_madt_entry_handler handler,
+			     acpi_table_entry_handler handler,
 			     unsigned int max_entries)
 {
-	struct acpi_table_header *madt = NULL;
+	struct acpi_table_header *table_header = NULL;
 	struct acpi_subtable_header *entry;
 	unsigned int count = 0;
-	unsigned long madt_end;
+	unsigned long table_end;
 
 	if (!handler)
 		return -EINVAL;
 
-	/* Locate the MADT (if exists). There should only be one. */
-	acpi_get_table(id, 0, &madt);
+	/* Locate the table (if exists). There should only be one. */
+	acpi_get_table(id, 0, &table_header);
 
-	if (!madt) {
+	if (!table_header) {
 		printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
 		return -ENODEV;
 	}
 
-	madt_end = (unsigned long)madt + madt->length;
+	table_end = (unsigned long)table_header + table_header->length;
 
 	/* Parse all entries looking for a match. */
 
 	entry = (struct acpi_subtable_header *)
-	    ((unsigned long)madt + madt_size);
+	    ((unsigned long)table_header + table_size);
 
 	while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
-	       madt_end) {
+	       table_end) {
 		if (entry->type == entry_id
 		    && (!max_entries || count++ < max_entries))
-			if (handler(entry, madt_end))
+			if (handler(entry, table_end))
 				return -EINVAL;
 
 		entry = (struct acpi_subtable_header *)
@@ -218,13 +218,22 @@
 
 int __init
 acpi_table_parse_madt(enum acpi_madt_type id,
-		      acpi_madt_entry_handler handler, unsigned int max_entries)
+		      acpi_table_entry_handler handler, unsigned int max_entries)
 {
-	return acpi_table_parse_madt_family(ACPI_SIG_MADT,
+	return acpi_table_parse_entries(ACPI_SIG_MADT,
 					    sizeof(struct acpi_table_madt), id,
 					    handler, max_entries);
 }
 
+/**
+ * acpi_table_parse - find table with @id, run @handler on it
+ *
+ * @id: table id to find
+ * @handler: handler to run
+ *
+ * Scan the ACPI System Descriptor Table (STD) for a table matching @id,
+ * run @handler on it.  Return 0 if table found, return on if not.
+ */
 int __init acpi_table_parse(char *id, acpi_table_handler handler)
 {
 	struct acpi_table_header *table = NULL;
@@ -234,9 +243,9 @@
 	acpi_get_table(id, 0, &table);
 	if (table) {
 		handler(table);
-		return 1;
-	} else
 		return 0;
+	} else
+		return 1;
 }
 
 /*
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 807978d..417ef5f 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -338,9 +338,9 @@
 	int i;
 	acpi_status status = AE_NOT_EXIST;
 
-	ACPI_FUNCTION_TRACE(acpi_unload_table);
+	ACPI_FUNCTION_TRACE(acpi_unload_table_id);
 
-	/* Find table from the requested type list */
+	/* Find table in the global table list */
 	for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
 		if (id != acpi_gbl_root_table_list.tables[i].owner_id) {
 			continue;
@@ -352,8 +352,9 @@
 		* simply a position within the hierarchy
 		*/
 		acpi_tb_delete_namespace_by_owner(i);
-		acpi_tb_release_owner_id(i);
+		status = acpi_tb_release_owner_id(i);
 		acpi_tb_set_table_loaded_flag(i, FALSE);
+		break;
 	}
 	return_ACPI_STATUS(status);
 }
@@ -408,7 +409,7 @@
 		}
 
 		if (!acpi_gbl_permanent_mmap) {
-			acpi_gbl_root_table_list.tables[i].pointer = 0;
+			acpi_gbl_root_table_list.tables[i].pointer = NULL;
 		}
 
 		return (status);
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 986afd4..0ae8b93 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -47,7 +47,6 @@
 
 #define ACPI_THERMAL_COMPONENT		0x04000000
 #define ACPI_THERMAL_CLASS		"thermal_zone"
-#define ACPI_THERMAL_DRIVER_NAME	"ACPI Thermal Zone Driver"
 #define ACPI_THERMAL_DEVICE_NAME	"Thermal Zone"
 #define ACPI_THERMAL_FILE_STATE		"state"
 #define ACPI_THERMAL_FILE_TEMPERATURE	"temperature"
@@ -71,10 +70,10 @@
 #define CELSIUS_TO_KELVIN(t)	((t+273)*10)
 
 #define _COMPONENT		ACPI_THERMAL_COMPONENT
-ACPI_MODULE_NAME("acpi_thermal")
+ACPI_MODULE_NAME("thermal");
 
 MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME);
+MODULE_DESCRIPTION("ACPI Thermal Zone Driver");
 MODULE_LICENSE("GPL");
 
 static int tzp;
@@ -99,7 +98,7 @@
 					  size_t, loff_t *);
 
 static struct acpi_driver acpi_thermal_driver = {
-	.name = ACPI_THERMAL_DRIVER_NAME,
+	.name = "thermal",
 	.class = ACPI_THERMAL_CLASS,
 	.ids = ACPI_THERMAL_HID,
 	.ops = {
@@ -270,7 +269,7 @@
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "Polling frequency set to %lu seconds\n",
-			  tz->polling_frequency));
+			  tz->polling_frequency/10));
 
 	return 0;
 }
@@ -1357,28 +1356,32 @@
 static int acpi_thermal_resume(struct acpi_device *device)
 {
 	struct acpi_thermal *tz = NULL;
-	int i;
+	int i, j, power_state, result;
+
 
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
 	tz = acpi_driver_data(device);
 
-	acpi_thermal_get_temperature(tz);
-
 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
-		if (tz->trips.active[i].flags.valid) {
- 			tz->temperature = tz->trips.active[i].temperature;
-			tz->trips.active[i].flags.enabled = 0;
-
-			acpi_thermal_active(tz);
-
-			tz->state.active |= tz->trips.active[i].flags.enabled;
-			tz->state.active_index = i;
+		if (!(&tz->trips.active[i]))
+			break;
+		if (!tz->trips.active[i].flags.valid)
+			break;
+		tz->trips.active[i].flags.enabled = 1;
+		for (j = 0; j < tz->trips.active[i].devices.count; j++) {
+			result = acpi_bus_get_power(tz->trips.active[i].devices.
+			    handles[j], &power_state);
+			if (result || (power_state != ACPI_STATE_D0)) {
+				tz->trips.active[i].flags.enabled = 0;
+				break;
+			}
 		}
+		tz->state.active |= tz->trips.active[i].flags.enabled;
 	}
 
- 	acpi_thermal_check(tz);
+	acpi_thermal_check(tz);
 
 	return AE_OK;
 }
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index d9b651f..faf8a52 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -125,7 +125,7 @@
 	union acpi_object in_objs[1];
 	acpi_status status;
 
-	params.count = sizeof(in_objs) / sizeof(in_objs[0]);
+	params.count = ARRAY_SIZE(in_objs);
 	params.pointer = in_objs;
 	in_objs[0].type = ACPI_TYPE_INTEGER;
 	in_objs[0].integer.value = val;
@@ -561,10 +561,6 @@
 	if (acpi_disabled)
 		return -ENODEV;
 
-	if (!acpi_specific_hotkey_enabled) {
-		printk(MY_INFO "Using generic hotkey driver\n");
-		return -ENODEV;
-	}
 	/* simple device detection: look for HCI method */
 	if (is_valid_acpi_path(METHOD_HCI_1))
 		method_hci = METHOD_HCI_1;
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index f777ceb..673a0ca 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -170,7 +170,6 @@
 			acpi_os_delete_mutex(object->mutex.os_mutex);
 			acpi_gbl_global_lock_mutex = NULL;
 		} else {
-			acpi_ex_unlink_mutex(object);
 			acpi_os_delete_mutex(object->mutex.os_mutex);
 		}
 		break;
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 68a809f..34f1575 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -31,7 +31,7 @@
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT		ACPI_BUS_COMPONENT
-ACPI_MODULE_NAME("acpi_utils")
+ACPI_MODULE_NAME("utils");
 
 /* --------------------------------------------------------------------------
                             Object Evaluation Helpers
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index e0b97ad..bf525cc 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -40,7 +40,6 @@
 
 #define ACPI_VIDEO_COMPONENT		0x08000000
 #define ACPI_VIDEO_CLASS		"video"
-#define ACPI_VIDEO_DRIVER_NAME		"ACPI Video Driver"
 #define ACPI_VIDEO_BUS_NAME		"Video Bus"
 #define ACPI_VIDEO_DEVICE_NAME		"Video Device"
 #define ACPI_VIDEO_NOTIFY_SWITCH	0x80
@@ -65,17 +64,17 @@
 #define ACPI_VIDEO_DISPLAY_LCD	4
 
 #define _COMPONENT		ACPI_VIDEO_COMPONENT
-ACPI_MODULE_NAME("acpi_video")
+ACPI_MODULE_NAME("video");
 
-    MODULE_AUTHOR("Bruno Ducrot");
-MODULE_DESCRIPTION(ACPI_VIDEO_DRIVER_NAME);
+MODULE_AUTHOR("Bruno Ducrot");
+MODULE_DESCRIPTION("ACPI Video Driver");
 MODULE_LICENSE("GPL");
 
 static int acpi_video_bus_add(struct acpi_device *device);
 static int acpi_video_bus_remove(struct acpi_device *device, int type);
 
 static struct acpi_driver acpi_video_bus = {
-	.name = ACPI_VIDEO_DRIVER_NAME,
+	.name = "video",
 	.class = ACPI_VIDEO_CLASS,
 	.ids = ACPI_VIDEO_HID,
 	.ops = {
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 3747457fe..4af0a4b 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -161,6 +161,19 @@
 	depends on IDE=y && !BLK_DEV_IDE_SATA && (SATA_AHCI || ATA_PIIX)
 	default y
 
+config SATA_ACPI
+	bool
+	depends on ACPI && PCI
+	default y
+	help
+	  This option adds support for SATA-related ACPI objects.
+	  These ACPI objects add the ability to retrieve taskfiles
+	  from the ACPI BIOS and write them to the disk controller.
+	  These objects may be related to performance, security,
+	  power management, or other areas.
+	  You can disable this at kernel boot time by using the
+	  option libata.noacpi=1
+
 config PATA_ALI
 	tristate "ALi PATA support (Experimental)"
 	depends on PCI && EXPERIMENTAL
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index cd096f0..74298af 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -66,4 +66,4 @@
 obj-$(CONFIG_PATA_LEGACY)	+= pata_legacy.o
 
 libata-objs	:= libata-core.o libata-scsi.o libata-sff.o libata-eh.o
-
+libata-$(CONFIG_SATA_ACPI) += libata-acpi.o
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
new file mode 100644
index 0000000..b4e8be5
--- /dev/null
+++ b/drivers/ata/libata-acpi.c
@@ -0,0 +1,698 @@
+/*
+ * libata-acpi.c
+ * Provides ACPI support for PATA/SATA.
+ *
+ * Copyright (C) 2006 Intel Corp.
+ * Copyright (C) 2006 Randy Dunlap
+ */
+
+#include <linux/ata.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/acpi.h>
+#include <linux/libata.h>
+#include <linux/pci.h>
+#include "libata.h"
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acnames.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
+#include <acpi/acexcep.h>
+#include <acpi/acmacros.h>
+#include <acpi/actypes.h>
+
+#define SATA_ROOT_PORT(x)	(((x) >> 16) & 0xffff)
+#define SATA_PORT_NUMBER(x)	((x) & 0xffff)	/* or NO_PORT_MULT */
+#define NO_PORT_MULT		0xffff
+#define SATA_ADR_RSVD		0xffffffff
+
+#define REGS_PER_GTF		7
+struct taskfile_array {
+	u8	tfa[REGS_PER_GTF];	/* regs. 0x1f1 - 0x1f7 */
+};
+
+
+/**
+ * sata_get_dev_handle - finds acpi_handle and PCI device.function
+ * @dev: device to locate
+ * @handle: returned acpi_handle for @dev
+ * @pcidevfn: return PCI device.func for @dev
+ *
+ * This function is somewhat SATA-specific.  Or at least the
+ * PATA & SATA versions of this function are different,
+ * so it's not entirely generic code.
+ *
+ * Returns 0 on success, <0 on error.
+ */
+static int sata_get_dev_handle(struct device *dev, acpi_handle *handle,
+					acpi_integer *pcidevfn)
+{
+	struct pci_dev	*pci_dev;
+	acpi_integer	addr;
+
+	pci_dev = to_pci_dev(dev);	/* NOTE: PCI-specific */
+	/* Please refer to the ACPI spec for the syntax of _ADR. */
+	addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
+	*pcidevfn = addr;
+	*handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
+	if (!*handle)
+		return -ENODEV;
+	return 0;
+}
+
+/**
+ * pata_get_dev_handle - finds acpi_handle and PCI device.function
+ * @dev: device to locate
+ * @handle: returned acpi_handle for @dev
+ * @pcidevfn: return PCI device.func for @dev
+ *
+ * The PATA and SATA versions of this function are different.
+ *
+ * Returns 0 on success, <0 on error.
+ */
+static int pata_get_dev_handle(struct device *dev, acpi_handle *handle,
+				acpi_integer *pcidevfn)
+{
+	unsigned int bus, devnum, func;
+	acpi_integer addr;
+	acpi_handle dev_handle, parent_handle;
+	struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER,
+					.pointer = NULL};
+	acpi_status status;
+	struct acpi_device_info	*dinfo = NULL;
+	int ret = -ENODEV;
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	bus = pdev->bus->number;
+	devnum = PCI_SLOT(pdev->devfn);
+	func = PCI_FUNC(pdev->devfn);
+
+	dev_handle = DEVICE_ACPI_HANDLE(dev);
+	parent_handle = DEVICE_ACPI_HANDLE(dev->parent);
+
+	status = acpi_get_object_info(parent_handle, &buffer);
+	if (ACPI_FAILURE(status))
+		goto err;
+
+	dinfo = buffer.pointer;
+	if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
+	    dinfo->address == bus) {
+		/* ACPI spec for _ADR for PCI bus: */
+		addr = (acpi_integer)(devnum << 16 | func);
+		*pcidevfn = addr;
+		*handle = dev_handle;
+	} else {
+		goto err;
+	}
+
+	if (!*handle)
+		goto err;
+	ret = 0;
+err:
+	kfree(dinfo);
+	return ret;
+}
+
+struct walk_info {		/* can be trimmed some */
+	struct device	*dev;
+	struct acpi_device *adev;
+	acpi_handle	handle;
+	acpi_integer	pcidevfn;
+	unsigned int	drivenum;
+	acpi_handle	obj_handle;
+	struct ata_port *ataport;
+	struct ata_device *atadev;
+	u32		sata_adr;
+	int		status;
+	char		basepath[ACPI_PATHNAME_MAX];
+	int		basepath_len;
+};
+
+static acpi_status get_devices(acpi_handle handle,
+				u32 level, void *context, void **return_value)
+{
+	acpi_status		status;
+	struct walk_info	*winfo = context;
+	struct acpi_buffer	namebuf = {ACPI_ALLOCATE_BUFFER, NULL};
+	char			*pathname;
+	struct acpi_buffer	buffer;
+	struct acpi_device_info	*dinfo;
+
+	status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &namebuf);
+	if (status)
+		goto ret;
+	pathname = namebuf.pointer;
+
+	buffer.length = ACPI_ALLOCATE_BUFFER;
+	buffer.pointer = NULL;
+	status = acpi_get_object_info(handle, &buffer);
+	if (ACPI_FAILURE(status))
+		goto out2;
+
+	dinfo = buffer.pointer;
+
+	/* find full device path name for pcidevfn */
+	if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
+	    dinfo->address == winfo->pcidevfn) {
+		if (ata_msg_probe(winfo->ataport))
+			ata_dev_printk(winfo->atadev, KERN_DEBUG,
+				":%s: matches pcidevfn (0x%llx)\n",
+				pathname, winfo->pcidevfn);
+		strlcpy(winfo->basepath, pathname,
+			sizeof(winfo->basepath));
+		winfo->basepath_len = strlen(pathname);
+		goto out;
+	}
+
+	/* if basepath is not yet known, ignore this object */
+	if (!winfo->basepath_len)
+		goto out;
+
+	/* if this object is in scope of basepath, maybe use it */
+	if (strncmp(pathname, winfo->basepath,
+	    winfo->basepath_len) == 0) {
+		if (!(dinfo->valid & ACPI_VALID_ADR))
+			goto out;
+		if (ata_msg_probe(winfo->ataport))
+			ata_dev_printk(winfo->atadev, KERN_DEBUG,
+				"GOT ONE: (%s) root_port = 0x%llx,"
+				" port_num = 0x%llx\n", pathname,
+				SATA_ROOT_PORT(dinfo->address),
+				SATA_PORT_NUMBER(dinfo->address));
+		/* heuristics: */
+		if (SATA_PORT_NUMBER(dinfo->address) != NO_PORT_MULT)
+			if (ata_msg_probe(winfo->ataport))
+				ata_dev_printk(winfo->atadev,
+					KERN_DEBUG, "warning: don't"
+					" know how to handle SATA port"
+					" multiplier\n");
+		if (SATA_ROOT_PORT(dinfo->address) ==
+			winfo->ataport->port_no &&
+		    SATA_PORT_NUMBER(dinfo->address) == NO_PORT_MULT) {
+			if (ata_msg_probe(winfo->ataport))
+				ata_dev_printk(winfo->atadev,
+					KERN_DEBUG,
+					"THIS ^^^^^ is the requested"
+					" SATA drive (handle = 0x%p)\n",
+					handle);
+			winfo->sata_adr = dinfo->address;
+			winfo->obj_handle = handle;
+		}
+	}
+out:
+	kfree(dinfo);
+out2:
+	kfree(pathname);
+
+ret:
+	return status;
+}
+
+/* Get the SATA drive _ADR object. */
+static int get_sata_adr(struct device *dev, acpi_handle handle,
+			acpi_integer pcidevfn, unsigned int drive,
+			struct ata_port *ap,
+			struct ata_device *atadev, u32 *dev_adr)
+{
+	acpi_status	status;
+	struct walk_info *winfo;
+	int		err = -ENOMEM;
+
+	winfo = kzalloc(sizeof(struct walk_info), GFP_KERNEL);
+	if (!winfo)
+		goto out;
+
+	winfo->dev = dev;
+	winfo->atadev = atadev;
+	winfo->ataport = ap;
+	if (acpi_bus_get_device(handle, &winfo->adev) < 0)
+		if (ata_msg_probe(ap))
+			ata_dev_printk(winfo->atadev, KERN_DEBUG,
+				"acpi_bus_get_device failed\n");
+	winfo->handle = handle;
+	winfo->pcidevfn = pcidevfn;
+	winfo->drivenum = drive;
+
+	status = acpi_get_devices(NULL, get_devices, winfo, NULL);
+	if (ACPI_FAILURE(status)) {
+		if (ata_msg_probe(ap))
+			ata_dev_printk(winfo->atadev, KERN_DEBUG,
+				"%s: acpi_get_devices failed\n",
+				__FUNCTION__);
+		err = -ENODEV;
+	} else {
+		*dev_adr = winfo->sata_adr;
+		atadev->obj_handle = winfo->obj_handle;
+		err = 0;
+	}
+	kfree(winfo);
+out:
+	return err;
+}
+
+/**
+ * do_drive_get_GTF - get the drive bootup default taskfile settings
+ * @ap: the ata_port for the drive
+ * @ix: target ata_device (drive) index
+ * @gtf_length: number of bytes of _GTF data returned at @gtf_address
+ * @gtf_address: buffer containing _GTF taskfile arrays
+ *
+ * This applies to both PATA and SATA drives.
+ *
+ * The _GTF method has no input parameters.
+ * It returns a variable number of register set values (registers
+ * hex 1F1..1F7, taskfiles).
+ * The <variable number> is not known in advance, so have ACPI-CA
+ * allocate the buffer as needed and return it, then free it later.
+ *
+ * The returned @gtf_length and @gtf_address are only valid if the
+ * function return value is 0.
+ */
+static int do_drive_get_GTF(struct ata_port *ap, int ix,
+			unsigned int *gtf_length, unsigned long *gtf_address,
+			unsigned long *obj_loc)
+{
+	acpi_status			status;
+	acpi_handle			dev_handle = NULL;
+	acpi_handle			chan_handle, drive_handle;
+	acpi_integer			pcidevfn = 0;
+	u32				dev_adr;
+	struct acpi_buffer		output;
+	union acpi_object 		*out_obj;
+	struct device			*dev = ap->host->dev;
+	struct ata_device		*atadev = &ap->device[ix];
+	int				err = -ENODEV;
+
+	*gtf_length = 0;
+	*gtf_address = 0UL;
+	*obj_loc = 0UL;
+
+	if (noacpi)
+		return 0;
+
+	if (ata_msg_probe(ap))
+		ata_dev_printk(atadev, KERN_DEBUG,
+			"%s: ENTER: ap->id: %d, port#: %d\n",
+			__FUNCTION__, ap->id, ap->port_no);
+
+	if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED)) {
+		if (ata_msg_probe(ap))
+			ata_dev_printk(atadev, KERN_DEBUG, "%s: ERR: "
+				"ata_dev_present: %d, PORT_DISABLED: %lu\n",
+				__FUNCTION__, ata_dev_enabled(atadev),
+				ap->flags & ATA_FLAG_DISABLED);
+		goto out;
+	}
+
+	/* Don't continue if device has no _ADR method.
+	 * _GTF is intended for known motherboard devices. */
+	if (!(ap->cbl == ATA_CBL_SATA)) {
+		err = pata_get_dev_handle(dev, &dev_handle, &pcidevfn);
+		if (err < 0) {
+			if (ata_msg_probe(ap))
+				ata_dev_printk(atadev, KERN_DEBUG,
+					"%s: pata_get_dev_handle failed (%d)\n",
+					__FUNCTION__, err);
+			goto out;
+		}
+	} else {
+		err = sata_get_dev_handle(dev, &dev_handle, &pcidevfn);
+		if (err < 0) {
+			if (ata_msg_probe(ap))
+				ata_dev_printk(atadev, KERN_DEBUG,
+					"%s: sata_get_dev_handle failed (%d\n",
+					__FUNCTION__, err);
+			goto out;
+		}
+	}
+
+	/* Get this drive's _ADR info. if not already known. */
+	if (!atadev->obj_handle) {
+		if (!(ap->cbl == ATA_CBL_SATA)) {
+			/* get child objects of dev_handle == channel objects,
+	 		 * + _their_ children == drive objects */
+			/* channel is ap->port_no */
+			chan_handle = acpi_get_child(dev_handle,
+						ap->port_no);
+			if (ata_msg_probe(ap))
+				ata_dev_printk(atadev, KERN_DEBUG,
+					"%s: chan adr=%d: chan_handle=0x%p\n",
+					__FUNCTION__, ap->port_no,
+					chan_handle);
+			if (!chan_handle) {
+				err = -ENODEV;
+				goto out;
+			}
+			/* TBD: could also check ACPI object VALID bits */
+			drive_handle = acpi_get_child(chan_handle, ix);
+			if (!drive_handle) {
+				err = -ENODEV;
+				goto out;
+			}
+			dev_adr = ix;
+			atadev->obj_handle = drive_handle;
+		} else {	/* for SATA mode */
+			dev_adr = SATA_ADR_RSVD;
+			err = get_sata_adr(dev, dev_handle, pcidevfn, 0,
+					ap, atadev, &dev_adr);
+		}
+		if (err < 0 || dev_adr == SATA_ADR_RSVD ||
+		    !atadev->obj_handle) {
+			if (ata_msg_probe(ap))
+				ata_dev_printk(atadev, KERN_DEBUG,
+					"%s: get_sata/pata_adr failed: "
+					"err=%d, dev_adr=%u, obj_handle=0x%p\n",
+					__FUNCTION__, err, dev_adr,
+					atadev->obj_handle);
+			goto out;
+		}
+	}
+
+	/* Setting up output buffer */
+	output.length = ACPI_ALLOCATE_BUFFER;
+	output.pointer = NULL;	/* ACPI-CA sets this; save/free it later */
+
+	/* _GTF has no input parameters */
+	err = -EIO;
+	status = acpi_evaluate_object(atadev->obj_handle, "_GTF",
+					NULL, &output);
+	if (ACPI_FAILURE(status)) {
+		if (ata_msg_probe(ap))
+			ata_dev_printk(atadev, KERN_DEBUG,
+				"%s: Run _GTF error: status = 0x%x\n",
+				__FUNCTION__, status);
+		goto out;
+	}
+
+	if (!output.length || !output.pointer) {
+		if (ata_msg_probe(ap))
+			ata_dev_printk(atadev, KERN_DEBUG, "%s: Run _GTF: "
+				"length or ptr is NULL (0x%llx, 0x%p)\n",
+				__FUNCTION__,
+				(unsigned long long)output.length,
+				output.pointer);
+		kfree(output.pointer);
+		goto out;
+	}
+
+	out_obj = output.pointer;
+	if (out_obj->type != ACPI_TYPE_BUFFER) {
+		kfree(output.pointer);
+		if (ata_msg_probe(ap))
+			ata_dev_printk(atadev, KERN_DEBUG, "%s: Run _GTF: "
+				"error: expected object type of "
+				" ACPI_TYPE_BUFFER, got 0x%x\n",
+				__FUNCTION__, out_obj->type);
+		err = -ENOENT;
+		goto out;
+	}
+
+	if (!out_obj->buffer.length || !out_obj->buffer.pointer ||
+	    out_obj->buffer.length % REGS_PER_GTF) {
+		if (ata_msg_drv(ap))
+			ata_dev_printk(atadev, KERN_ERR,
+				"%s: unexpected GTF length (%d) or addr (0x%p)\n",
+				__FUNCTION__, out_obj->buffer.length,
+				out_obj->buffer.pointer);
+		err = -ENOENT;
+		goto out;
+	}
+
+	*gtf_length = out_obj->buffer.length;
+	*gtf_address = (unsigned long)out_obj->buffer.pointer;
+	*obj_loc = (unsigned long)out_obj;
+	if (ata_msg_probe(ap))
+		ata_dev_printk(atadev, KERN_DEBUG, "%s: returning "
+			"gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n",
+			__FUNCTION__, *gtf_length, *gtf_address, *obj_loc);
+	err = 0;
+out:
+	return err;
+}
+
+/**
+ * taskfile_load_raw - send taskfile registers to host controller
+ * @ap: Port to which output is sent
+ * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
+ *
+ * Outputs ATA taskfile to standard ATA host controller using MMIO
+ * or PIO as indicated by the ATA_FLAG_MMIO flag.
+ * Writes the control, feature, nsect, lbal, lbam, and lbah registers.
+ * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
+ * hob_lbal, hob_lbam, and hob_lbah.
+ *
+ * This function waits for idle (!BUSY and !DRQ) after writing
+ * registers.  If the control register has a new value, this
+ * function also waits for idle after writing control and before
+ * writing the remaining registers.
+ *
+ * LOCKING: TBD:
+ * Inherited from caller.
+ */
+static void taskfile_load_raw(struct ata_port *ap,
+				struct ata_device *atadev,
+				const struct taskfile_array *gtf)
+{
+	if (ata_msg_probe(ap))
+		ata_dev_printk(atadev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: "
+			"%02x %02x %02x %02x %02x %02x %02x\n",
+			__FUNCTION__,
+			gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
+			gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
+
+	if ((gtf->tfa[0] == 0) && (gtf->tfa[1] == 0) && (gtf->tfa[2] == 0)
+	    && (gtf->tfa[3] == 0) && (gtf->tfa[4] == 0) && (gtf->tfa[5] == 0)
+	    && (gtf->tfa[6] == 0))
+		return;
+
+	if (ap->ops->qc_issue) {
+		struct ata_taskfile tf;
+		unsigned int err;
+
+		ata_tf_init(atadev, &tf);
+
+		/* convert gtf to tf */
+		tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
+		tf.protocol = atadev->class == ATA_DEV_ATAPI ?
+			ATA_PROT_ATAPI_NODATA : ATA_PROT_NODATA;
+		tf.feature = gtf->tfa[0];	/* 0x1f1 */
+		tf.nsect   = gtf->tfa[1];	/* 0x1f2 */
+		tf.lbal    = gtf->tfa[2];	/* 0x1f3 */
+		tf.lbam    = gtf->tfa[3];	/* 0x1f4 */
+		tf.lbah    = gtf->tfa[4];	/* 0x1f5 */
+		tf.device  = gtf->tfa[5];	/* 0x1f6 */
+		tf.command = gtf->tfa[6];	/* 0x1f7 */
+
+		err = ata_exec_internal(atadev, &tf, NULL, DMA_NONE, NULL, 0);
+		if (err && ata_msg_probe(ap))
+			ata_dev_printk(atadev, KERN_ERR,
+				"%s: ata_exec_internal failed: %u\n",
+				__FUNCTION__, err);
+	} else
+		if (ata_msg_warn(ap))
+			ata_dev_printk(atadev, KERN_WARNING,
+				"%s: SATA driver is missing qc_issue function"
+				" entry points\n",
+				__FUNCTION__);
+}
+
+/**
+ * do_drive_set_taskfiles - write the drive taskfile settings from _GTF
+ * @ap: the ata_port for the drive
+ * @atadev: target ata_device
+ * @gtf_length: total number of bytes of _GTF taskfiles
+ * @gtf_address: location of _GTF taskfile arrays
+ *
+ * This applies to both PATA and SATA drives.
+ *
+ * Write {gtf_address, length gtf_length} in groups of
+ * REGS_PER_GTF bytes.
+ */
+static int do_drive_set_taskfiles(struct ata_port *ap,
+		struct ata_device *atadev, unsigned int gtf_length,
+		unsigned long gtf_address)
+{
+	int			err = -ENODEV;
+	int			gtf_count = gtf_length / REGS_PER_GTF;
+	int			ix;
+	struct taskfile_array	*gtf;
+
+	if (ata_msg_probe(ap))
+		ata_dev_printk(atadev, KERN_DEBUG,
+			"%s: ENTER: ap->id: %d, port#: %d\n",
+			__FUNCTION__, ap->id, ap->port_no);
+
+	if (noacpi || !(ap->cbl == ATA_CBL_SATA))
+		return 0;
+
+	if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED))
+		goto out;
+	if (!gtf_count)		/* shouldn't be here */
+		goto out;
+
+	if (gtf_length % REGS_PER_GTF) {
+		if (ata_msg_drv(ap))
+			ata_dev_printk(atadev, KERN_ERR,
+				"%s: unexpected GTF length (%d)\n",
+				__FUNCTION__, gtf_length);
+		goto out;
+	}
+
+	for (ix = 0; ix < gtf_count; ix++) {
+		gtf = (struct taskfile_array *)
+			(gtf_address + ix * REGS_PER_GTF);
+
+		/* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
+		taskfile_load_raw(ap, atadev, gtf);
+	}
+
+	err = 0;
+out:
+	return err;
+}
+
+/**
+ * ata_acpi_exec_tfs - get then write drive taskfile settings
+ * @ap: the ata_port for the drive
+ *
+ * This applies to both PATA and SATA drives.
+ */
+int ata_acpi_exec_tfs(struct ata_port *ap)
+{
+	int		ix;
+	int		ret =0;
+	unsigned int	gtf_length;
+	unsigned long	gtf_address;
+	unsigned long	obj_loc;
+
+	if (noacpi)
+		return 0;
+
+	for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
+		if (!ata_dev_enabled(&ap->device[ix]))
+			continue;
+
+		ret = do_drive_get_GTF(ap, ix,
+				&gtf_length, &gtf_address, &obj_loc);
+		if (ret < 0) {
+			if (ata_msg_probe(ap))
+				ata_port_printk(ap, KERN_DEBUG,
+					"%s: get_GTF error (%d)\n",
+					__FUNCTION__, ret);
+			break;
+		}
+
+		ret = do_drive_set_taskfiles(ap, &ap->device[ix],
+				gtf_length, gtf_address);
+		kfree((void *)obj_loc);
+		if (ret < 0) {
+			if (ata_msg_probe(ap))
+				ata_port_printk(ap, KERN_DEBUG,
+					"%s: set_taskfiles error (%d)\n",
+					__FUNCTION__, ret);
+			break;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * ata_acpi_push_id - send Identify data to drive
+ * @ap: the ata_port for the drive
+ * @ix: drive index
+ *
+ * _SDD ACPI object: for SATA mode only
+ * Must be after Identify (Packet) Device -- uses its data
+ * ATM this function never returns a failure.  It is an optional
+ * method and if it fails for whatever reason, we should still
+ * just keep going.
+ */
+int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
+{
+	acpi_handle                     handle;
+	acpi_integer                    pcidevfn;
+	int                             err;
+	struct device                   *dev = ap->host->dev;
+	struct ata_device               *atadev = &ap->device[ix];
+	u32                             dev_adr;
+	acpi_status                     status;
+	struct acpi_object_list         input;
+	union acpi_object               in_params[1];
+
+	if (noacpi)
+		return 0;
+
+	if (ata_msg_probe(ap))
+		ata_dev_printk(atadev, KERN_DEBUG,
+			"%s: ap->id: %d, ix = %d, port#: %d\n",
+			__FUNCTION__, ap->id, ix, ap->port_no);
+
+	/* Don't continue if not a SATA device. */
+	if (!(ap->cbl == ATA_CBL_SATA)) {
+		if (ata_msg_probe(ap))
+			ata_dev_printk(atadev, KERN_DEBUG,
+				"%s: Not a SATA device\n", __FUNCTION__);
+		goto out;
+	}
+
+	/* Don't continue if device has no _ADR method.
+	 * _SDD is intended for known motherboard devices. */
+	err = sata_get_dev_handle(dev, &handle, &pcidevfn);
+	if (err < 0) {
+		if (ata_msg_probe(ap))
+			ata_dev_printk(atadev, KERN_DEBUG,
+				"%s: sata_get_dev_handle failed (%d\n",
+				__FUNCTION__, err);
+		goto out;
+	}
+
+	/* Get this drive's _ADR info, if not already known */
+	if (!atadev->obj_handle) {
+		dev_adr = SATA_ADR_RSVD;
+		err = get_sata_adr(dev, handle, pcidevfn, ix, ap, atadev,
+					&dev_adr);
+		if (err < 0 || dev_adr == SATA_ADR_RSVD ||
+			!atadev->obj_handle) {
+			if (ata_msg_probe(ap))
+				ata_dev_printk(atadev, KERN_DEBUG,
+					"%s: get_sata_adr failed: "
+					"err=%d, dev_adr=%u, obj_handle=0x%p\n",
+					__FUNCTION__, err, dev_adr,
+					atadev->obj_handle);
+			goto out;
+		}
+	}
+
+	/* Give the drive Identify data to the drive via the _SDD method */
+	/* _SDD: set up input parameters */
+	input.count = 1;
+	input.pointer = in_params;
+	in_params[0].type = ACPI_TYPE_BUFFER;
+	in_params[0].buffer.length = sizeof(atadev->id[0]) * ATA_ID_WORDS;
+	in_params[0].buffer.pointer = (u8 *)atadev->id;
+	/* Output buffer: _SDD has no output */
+
+	/* It's OK for _SDD to be missing too. */
+	swap_buf_le16(atadev->id, ATA_ID_WORDS);
+	status = acpi_evaluate_object(atadev->obj_handle, "_SDD", &input, NULL);
+	swap_buf_le16(atadev->id, ATA_ID_WORDS);
+
+	err = ACPI_FAILURE(status) ? -EIO : 0;
+	if (err < 0) {
+		if (ata_msg_probe(ap))
+			ata_dev_printk(atadev, KERN_DEBUG,
+				"ata%u(%u): %s _SDD error: status = 0x%x\n",
+				ap->id, ap->device->devno,
+				__FUNCTION__, status);
+	}
+
+	/* always return success */
+out:
+	return 0;
+}
+
+
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 2cf8251..e900c5e 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -93,6 +93,10 @@
 module_param(ata_probe_timeout, int, 0444);
 MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)");
 
+int noacpi;
+module_param(noacpi, int, 0444);
+MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set");
+
 MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("Library module for ATA devices");
 MODULE_LICENSE("GPL");
@@ -1564,6 +1568,16 @@
 		ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n",
 			       __FUNCTION__, ap->id, dev->devno);
 
+	/* set _SDD */
+	rc = ata_acpi_push_id(ap, dev->devno);
+	if (rc) {
+		ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n",
+			rc);
+	}
+
+	/* retrieve and execute the ATA task file of _GTF */
+	ata_acpi_exec_tfs(ap);
+
 	/* print device capabilities */
 	if (ata_msg_probe(ap))
 		ata_dev_printk(dev, KERN_DEBUG,
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 06ccf23..0ad7781 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -47,6 +47,7 @@
 extern int atapi_enabled;
 extern int atapi_dmadir;
 extern int libata_fua;
+extern int noacpi;
 extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
 extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
 			   u64 block, u32 n_block, unsigned int tf_flags,
@@ -87,6 +88,20 @@
 extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev,
 						 const struct ata_port_info *port);
 
+/* libata-acpi.c */
+#ifdef CONFIG_SATA_ACPI
+extern int ata_acpi_exec_tfs(struct ata_port *ap);
+extern int ata_acpi_push_id(struct ata_port *ap, unsigned int ix);
+#else
+static inline int ata_acpi_exec_tfs(struct ata_port *ap)
+{
+	return 0;
+}
+static inline int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
+{
+	return 0;
+}
+#endif
 
 /* libata-scsi.c */
 extern struct scsi_transport_template ata_scsi_transport_template;
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 472810f..253868e 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -324,27 +324,25 @@
 	return error;
 }
 
-static int device_add_attrs(struct bus_type * bus, struct device * dev)
+static int device_add_attrs(struct bus_type *bus, struct device *dev)
 {
 	int error = 0;
 	int i;
 
-	if (bus->dev_attrs) {
-		for (i = 0; attr_name(bus->dev_attrs[i]); i++) {
-			error = device_create_file(dev,&bus->dev_attrs[i]);
-			if (error)
-				goto Err;
+	if (!bus->dev_attrs)
+		return 0;
+
+	for (i = 0; attr_name(bus->dev_attrs[i]); i++) {
+		error = device_create_file(dev,&bus->dev_attrs[i]);
+		if (error) {
+			while (--i >= 0)
+				device_remove_file(dev, &bus->dev_attrs[i]);
+			break;
 		}
 	}
- Done:
 	return error;
- Err:
-	while (--i >= 0)
-		device_remove_file(dev,&bus->dev_attrs[i]);
-	goto Done;
 }
 
-
 static void device_remove_attrs(struct bus_type * bus, struct device * dev)
 {
 	int i;
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 96def1d..1417e5c 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -163,8 +163,7 @@
 void class_unregister(struct class * cls)
 {
 	pr_debug("device class '%s': unregistering\n", cls->name);
-	if (cls->virtual_dir)
-		kobject_unregister(cls->virtual_dir);
+	kobject_unregister(cls->virtual_dir);
 	remove_class_attrs(cls);
 	subsystem_unregister(&cls->subsys);
 }
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 7fd095e..fe7ef33 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -103,7 +103,7 @@
 #endif
 
 /*
- * register_cpu - Setup a driverfs device for a CPU.
+ * register_cpu - Setup a sysfs device for a CPU.
  * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
  *	  sysfs for this CPU.
  * @num - CPU number to use when creating the device.
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 475e33f..cae346e 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -133,7 +133,7 @@
 
 
 /*
- * register_node - Setup a driverfs device for a node.
+ * register_node - Setup a sysfs device for a node.
  * @num - Node number to use when creating the device.
  *
  * Initialize and register the node device.
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 85c1618..294e9cb 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -1146,7 +1146,7 @@
 				rio_dprintk(RIO_DEBUG_INIT, "Enabling interrupts on rio card.\n");
 				hp->Mode |= RIO_PCI_INT_ENABLE;
 			} else
-				hp->Mode &= !RIO_PCI_INT_ENABLE;
+				hp->Mode &= ~RIO_PCI_INT_ENABLE;
 			rio_dprintk(RIO_DEBUG_INIT, "New Mode: %x\n", hp->Mode);
 			rio_start_card_running(hp);
 		}
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
index 81fb3de..4a328ba 100644
--- a/drivers/char/watchdog/machzwd.c
+++ b/drivers/char/watchdog/machzwd.c
@@ -324,7 +324,7 @@
 			return put_user(0, p);
 
 		case WDIOC_KEEPALIVE:
-			zf_ping(NULL);
+			zf_ping(0);
 			break;
 
 		default:
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 891ef6d..c3d4856 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -73,6 +73,17 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called adm1026.
 
+config SENSORS_ADM1029
+	tristate "Analog Devices ADM1029"
+	depends on HWMON && I2C && EXPERIMENTAL
+	help
+	  If you say yes here you get support for Analog Devices ADM1029
+	  sensor chip.
+	  Very rare chip, please let us know you use it.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called adm1029.
+
 config SENSORS_ADM1031
 	tristate "Analog Devices ADM1031 and compatibles"
 	depends on HWMON && I2C && EXPERIMENTAL
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 3166112..4165c27 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -17,6 +17,7 @@
 obj-$(CONFIG_SENSORS_ADM1021)	+= adm1021.o
 obj-$(CONFIG_SENSORS_ADM1025)	+= adm1025.o
 obj-$(CONFIG_SENSORS_ADM1026)	+= adm1026.o
+obj-$(CONFIG_SENSORS_ADM1029)	+= adm1029.o
 obj-$(CONFIG_SENSORS_ADM1031)	+= adm1031.o
 obj-$(CONFIG_SENSORS_ADM9240)	+= adm9240.o
 obj-$(CONFIG_SENSORS_AMS)	+= ams/
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c
index b1dc63e..bede4d9 100644
--- a/drivers/hwmon/abituguru.c
+++ b/drivers/hwmon/abituguru.c
@@ -1267,30 +1267,42 @@
 	printk(KERN_INFO ABIT_UGURU_NAME ": found Abit uGuru\n");
 
 	/* Register sysfs hooks */
-	data->class_dev = hwmon_device_register(&pdev->dev);
-	if (IS_ERR(data->class_dev)) {
-		res = PTR_ERR(data->class_dev);
-		goto abituguru_probe_error;
-	}
 	for (i = 0; i < sysfs_attr_i; i++)
-		device_create_file(&pdev->dev, &data->sysfs_attr[i].dev_attr);
+		if (device_create_file(&pdev->dev,
+				&data->sysfs_attr[i].dev_attr))
+			goto abituguru_probe_error;
 	for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++)
-		device_create_file(&pdev->dev,
-			&abituguru_sysfs_attr[i].dev_attr);
+		if (device_create_file(&pdev->dev,
+				&abituguru_sysfs_attr[i].dev_attr))
+			goto abituguru_probe_error;
 
-	return 0;
+	data->class_dev = hwmon_device_register(&pdev->dev);
+	if (!IS_ERR(data->class_dev))
+		return 0; /* success */
 
+	res = PTR_ERR(data->class_dev);
 abituguru_probe_error:
+	for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++)
+		device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr);
+	for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++)
+		device_remove_file(&pdev->dev,
+			&abituguru_sysfs_attr[i].dev_attr);
 	kfree(data);
 	return res;
 }
 
 static int __devexit abituguru_remove(struct platform_device *pdev)
 {
+	int i;
 	struct abituguru_data *data = platform_get_drvdata(pdev);
 
 	platform_set_drvdata(pdev, NULL);
 	hwmon_device_unregister(data->class_dev);
+	for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++)
+		device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr);
+	for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++)
+		device_remove_file(&pdev->dev,
+			&abituguru_sysfs_attr[i].dev_attr);
 	kfree(data);
 
 	return 0;
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
index b4618b2..ba80cd3 100644
--- a/drivers/hwmon/adm1026.c
+++ b/drivers/hwmon/adm1026.c
@@ -261,7 +261,6 @@
 struct adm1026_data {
 	struct i2c_client client;
 	struct class_device *class_dev;
-	struct mutex lock;
 	enum chips type;
 
 	struct mutex update_lock;
diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c
new file mode 100644
index 0000000..73ce31b
--- /dev/null
+++ b/drivers/hwmon/adm1029.c
@@ -0,0 +1,508 @@
+/*
+ * adm1029.c - Part of lm_sensors, Linux kernel modules for hardware monitoring
+ *
+ * Copyright (C) 2006 Corentin LABBE <corentin.labbe@geomatys.fr>
+ *
+ * Based on LM83 Driver by Jean Delvare <khali@linux-fr.org>
+ *
+ * Give only processor, motherboard temperatures and fan tachs
+ * Very rare chip please let me know if you use it
+ *
+ * http://www.analog.com/UploadedFiles/Data_Sheets/ADM1029.pdf
+ *
+ *
+ * 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 version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/hwmon.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+/*
+ * Addresses to scan
+ */
+
+static unsigned short normal_i2c[] = {
+	0x28, 0x29, 0x2a,
+	0x2b, 0x2c, 0x2d,
+	0x2e, 0x2f, I2C_CLIENT_END
+};
+
+/*
+ * Insmod parameters
+ */
+
+I2C_CLIENT_INSMOD_1(adm1029);
+
+/*
+ * The ADM1029 registers
+ * Manufacturer ID is 0x41 for Analog Devices
+ */
+
+#define ADM1029_REG_MAN_ID			0x0D
+#define ADM1029_REG_CHIP_ID			0x0E
+#define ADM1029_REG_CONFIG			0x01
+#define ADM1029_REG_NB_FAN_SUPPORT		0x02
+
+#define ADM1029_REG_TEMP_DEVICES_INSTALLED	0x06
+
+#define ADM1029_REG_LOCAL_TEMP			0xA0
+#define ADM1029_REG_REMOTE1_TEMP		0xA1
+#define ADM1029_REG_REMOTE2_TEMP		0xA2
+
+#define ADM1029_REG_LOCAL_TEMP_HIGH		0x90
+#define ADM1029_REG_REMOTE1_TEMP_HIGH		0x91
+#define ADM1029_REG_REMOTE2_TEMP_HIGH		0x92
+
+#define ADM1029_REG_LOCAL_TEMP_LOW		0x98
+#define ADM1029_REG_REMOTE1_TEMP_LOW		0x99
+#define ADM1029_REG_REMOTE2_TEMP_LOW		0x9A
+
+#define ADM1029_REG_FAN1			0x70
+#define ADM1029_REG_FAN2			0x71
+
+#define ADM1029_REG_FAN1_MIN			0x78
+#define ADM1029_REG_FAN2_MIN			0x79
+
+#define ADM1029_REG_FAN1_CONFIG			0x68
+#define ADM1029_REG_FAN2_CONFIG			0x69
+
+#define TEMP_FROM_REG(val)	((val) * 1000)
+
+#define DIV_FROM_REG(val)	( 1 << (((val) >> 6) - 1))
+
+/* Registers to be checked by adm1029_update_device() */
+static const u8 ADM1029_REG_TEMP[] = {
+	ADM1029_REG_LOCAL_TEMP,
+	ADM1029_REG_REMOTE1_TEMP,
+	ADM1029_REG_REMOTE2_TEMP,
+	ADM1029_REG_LOCAL_TEMP_HIGH,
+	ADM1029_REG_REMOTE1_TEMP_HIGH,
+	ADM1029_REG_REMOTE2_TEMP_HIGH,
+	ADM1029_REG_LOCAL_TEMP_LOW,
+	ADM1029_REG_REMOTE1_TEMP_LOW,
+	ADM1029_REG_REMOTE2_TEMP_LOW,
+};
+
+static const u8 ADM1029_REG_FAN[] = {
+	ADM1029_REG_FAN1,
+	ADM1029_REG_FAN2,
+	ADM1029_REG_FAN1_MIN,
+	ADM1029_REG_FAN2_MIN,
+};
+
+static const u8 ADM1029_REG_FAN_DIV[] = {
+	ADM1029_REG_FAN1_CONFIG,
+	ADM1029_REG_FAN2_CONFIG,
+};
+
+/*
+ * Functions declaration
+ */
+
+static int adm1029_attach_adapter(struct i2c_adapter *adapter);
+static int adm1029_detect(struct i2c_adapter *adapter, int address, int kind);
+static int adm1029_detach_client(struct i2c_client *client);
+static struct adm1029_data *adm1029_update_device(struct device *dev);
+static int adm1029_init_client(struct i2c_client *client);
+
+/*
+ * Driver data (common to all clients)
+ */
+
+static struct i2c_driver adm1029_driver = {
+	.driver = {
+		.name = "adm1029",
+	},
+	.attach_adapter = adm1029_attach_adapter,
+	.detach_client = adm1029_detach_client,
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct adm1029_data {
+	struct i2c_client client;
+	struct class_device *class_dev;
+	struct mutex update_lock;
+	char valid;		/* zero until following fields are valid */
+	unsigned long last_updated;	/* in jiffies */
+
+	/* registers values, signed for temperature, unsigned for other stuff */
+	s8 temp[ARRAY_SIZE(ADM1029_REG_TEMP)];
+	u8 fan[ARRAY_SIZE(ADM1029_REG_FAN)];
+	u8 fan_div[ARRAY_SIZE(ADM1029_REG_FAN_DIV)];
+};
+
+/*
+ * Sysfs stuff
+ */
+
+static ssize_t
+show_temp(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct adm1029_data *data = adm1029_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index]));
+}
+
+static ssize_t
+show_fan(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct adm1029_data *data = adm1029_update_device(dev);
+	u16 val;
+	if (data->fan[attr->index] == 0 || data->fan_div[attr->index] == 0
+	    || data->fan[attr->index] == 255) {
+		return sprintf(buf, "0\n");
+	}
+
+	val = 1880 * 120 / DIV_FROM_REG(data->fan_div[attr->index])
+	    / data->fan[attr->index];
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t
+show_fan_div(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct adm1029_data *data = adm1029_update_device(dev);
+	if (data->fan_div[attr->index] == 0)
+		return sprintf(buf, "0\n");
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index]));
+}
+
+static ssize_t set_fan_div(struct device *dev,
+	    struct device_attribute *devattr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1029_data *data = i2c_get_clientdata(client);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	long val = simple_strtol(buf, NULL, 10);
+	u8 reg;
+
+	mutex_lock(&data->update_lock);
+
+	/*Read actual config */
+	reg = i2c_smbus_read_byte_data(client,
+				       ADM1029_REG_FAN_DIV[attr->index]);
+
+	switch (val) {
+	case 1:
+		val = 1;
+		break;
+	case 2:
+		val = 2;
+		break;
+	case 4:
+		val = 3;
+		break;
+	default:
+		mutex_unlock(&data->update_lock);
+		dev_err(&client->dev, "fan_div value %ld not "
+			"supported. Choose one of 1, 2 or 4!\n", val);
+		return -EINVAL;
+	}
+	/* Update the value */
+	reg = (reg & 0x3F) | (val << 6);
+
+	/* Write value */
+	i2c_smbus_write_byte_data(client,
+				  ADM1029_REG_FAN_DIV[attr->index], reg);
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+/*
+Access rights on sysfs, S_IRUGO stand for Is Readable by User, Group and Others
+			S_IWUSR stand for Is Writable by User
+*/
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
+
+static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO, show_temp, NULL, 4);
+static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO, show_temp, NULL, 5);
+
+static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO, show_temp, NULL, 6);
+static SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO, show_temp, NULL, 7);
+static SENSOR_DEVICE_ATTR(temp3_min, S_IRUGO, show_temp, NULL, 8);
+
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
+
+static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO, show_fan, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO, show_fan, NULL, 3);
+
+static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
+			  show_fan_div, set_fan_div, 0);
+static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
+			  show_fan_div, set_fan_div, 1);
+
+static struct attribute *adm1029_attributes[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_temp1_min.dev_attr.attr,
+	&sensor_dev_attr_temp1_max.dev_attr.attr,
+	&sensor_dev_attr_temp2_input.dev_attr.attr,
+	&sensor_dev_attr_temp2_min.dev_attr.attr,
+	&sensor_dev_attr_temp2_max.dev_attr.attr,
+	&sensor_dev_attr_temp3_input.dev_attr.attr,
+	&sensor_dev_attr_temp3_min.dev_attr.attr,
+	&sensor_dev_attr_temp3_max.dev_attr.attr,
+	&sensor_dev_attr_fan1_input.dev_attr.attr,
+	&sensor_dev_attr_fan2_input.dev_attr.attr,
+	&sensor_dev_attr_fan1_min.dev_attr.attr,
+	&sensor_dev_attr_fan2_min.dev_attr.attr,
+	&sensor_dev_attr_fan1_div.dev_attr.attr,
+	&sensor_dev_attr_fan2_div.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group adm1029_group = {
+	.attrs = adm1029_attributes,
+};
+
+/*
+ * Real code
+ */
+
+static int adm1029_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_probe(adapter, &addr_data, adm1029_detect);
+}
+
+/*
+ * The following function does more than just detection. If detection
+ * succeeds, it also registers the new chip.
+ */
+
+static int adm1029_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *client;
+	struct adm1029_data *data;
+	int err = 0;
+	const char *name = "";
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	if (!(data = kzalloc(sizeof(struct adm1029_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	client = &data->client;
+	i2c_set_clientdata(client, data);
+	client->addr = address;
+	client->adapter = adapter;
+	client->driver = &adm1029_driver;
+
+	/* Now we do the detection and identification. A negative kind
+	 * means that the driver was loaded with no force parameter
+	 * (default), so we must both detect and identify the chip
+	 * (actually there is only one possible kind of chip for now, adm1029).
+	 * A zero kind means that the driver was loaded with the force
+	 * parameter, the detection step shall be skipped. A positive kind
+	 * means that the driver was loaded with the force parameter and a
+	 * given kind of chip is requested, so both the detection and the
+	 * identification steps are skipped. */
+
+	/* Default to an adm1029 if forced */
+	if (kind == 0)
+		kind = adm1029;
+
+	/* ADM1029 doesn't have CHIP ID, check just MAN ID
+	 * For better detection we check also ADM1029_TEMP_DEVICES_INSTALLED,
+	 * ADM1029_REG_NB_FAN_SUPPORT and compare it with possible values
+	 * documented
+	 */
+
+	if (kind <= 0) {	/* identification */
+		u8 man_id, chip_id, temp_devices_installed, nb_fan_support;
+
+		man_id = i2c_smbus_read_byte_data(client, ADM1029_REG_MAN_ID);
+		chip_id = i2c_smbus_read_byte_data(client, ADM1029_REG_CHIP_ID);
+		temp_devices_installed = i2c_smbus_read_byte_data(client,
+					ADM1029_REG_TEMP_DEVICES_INSTALLED);
+		nb_fan_support = i2c_smbus_read_byte_data(client,
+						ADM1029_REG_NB_FAN_SUPPORT);
+		/* 0x41 is Analog Devices */
+		if (man_id == 0x41 && (temp_devices_installed & 0xf9) == 0x01
+		    && nb_fan_support == 0x03) {
+			if ((chip_id & 0xF0) == 0x00) {
+				kind = adm1029;
+			} else {
+				/* There are no "official" CHIP ID, so actually
+				 * we use Major/Minor revision for that */
+				printk(KERN_INFO
+				       "adm1029: Unknown major revision %x, "
+				       "please let us know\n", chip_id);
+			}
+		}
+
+		if (kind <= 0) {	/* identification failed */
+			pr_debug("adm1029: Unsupported chip (man_id=0x%02X, "
+				 "chip_id=0x%02X)\n", man_id, chip_id);
+			goto exit_free;
+		}
+	}
+
+	if (kind == adm1029) {
+		name = "adm1029";
+	}
+
+	/* We can fill in the remaining client fields */
+	strlcpy(client->name, name, I2C_NAME_SIZE);
+	mutex_init(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(client)))
+		goto exit_free;
+
+	/*
+	 * Initialize the ADM1029 chip
+	 * Check config register
+	 */
+	if (adm1029_init_client(client) == 0)
+		goto exit_detach;
+
+	/* Register sysfs hooks */
+	if ((err = sysfs_create_group(&client->dev.kobj, &adm1029_group)))
+		goto exit_detach;
+
+	data->class_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(data->class_dev)) {
+		err = PTR_ERR(data->class_dev);
+		goto exit_remove_files;
+	}
+
+	return 0;
+
+ exit_remove_files:
+	sysfs_remove_group(&client->dev.kobj, &adm1029_group);
+ exit_detach:
+	i2c_detach_client(client);
+ exit_free:
+	kfree(data);
+ exit:
+	return err;
+}
+
+static int adm1029_init_client(struct i2c_client *client)
+{
+	u8 config;
+	config = i2c_smbus_read_byte_data(client, ADM1029_REG_CONFIG);
+	if ((config & 0x10) == 0) {
+		i2c_smbus_write_byte_data(client, ADM1029_REG_CONFIG,
+					  config | 0x10);
+	}
+	/* recheck config */
+	config = i2c_smbus_read_byte_data(client, ADM1029_REG_CONFIG);
+	if ((config & 0x10) == 0) {
+		dev_err(&client->dev, "Initialization failed!\n");
+		return 0;
+	}
+	return 1;
+}
+
+static int adm1029_detach_client(struct i2c_client *client)
+{
+	struct adm1029_data *data = i2c_get_clientdata(client);
+	int err;
+
+	hwmon_device_unregister(data->class_dev);
+	sysfs_remove_group(&client->dev.kobj, &adm1029_group);
+
+	if ((err = i2c_detach_client(client)))
+		return err;
+
+	kfree(data);
+	return 0;
+}
+
+/*
+function that update the status of the chips (temperature for exemple)
+*/
+static struct adm1029_data *adm1029_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1029_data *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->update_lock);
+	/*
+	 * Use the "cache" Luke, don't recheck values
+	 * if there are already checked not a long time later
+	 */
+	if (time_after(jiffies, data->last_updated + HZ * 2)
+	 || !data->valid) {
+		int nr;
+
+		dev_dbg(&client->dev, "Updating adm1029 data\n");
+
+		for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_TEMP); nr++) {
+			data->temp[nr] =
+			    i2c_smbus_read_byte_data(client,
+						     ADM1029_REG_TEMP[nr]);
+		}
+		for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN); nr++) {
+			data->fan[nr] =
+			    i2c_smbus_read_byte_data(client,
+						     ADM1029_REG_FAN[nr]);
+		}
+		for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN_DIV); nr++) {
+			data->fan_div[nr] =
+			    i2c_smbus_read_byte_data(client,
+						     ADM1029_REG_FAN_DIV[nr]);
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
+/*
+	Common module stuff
+*/
+static int __init sensors_adm1029_init(void)
+{
+
+	return i2c_add_driver(&adm1029_driver);
+}
+
+static void __exit sensors_adm1029_exit(void)
+{
+
+	i2c_del_driver(&adm1029_driver);
+}
+
+MODULE_AUTHOR("Corentin LABBE <corentin.labbe@geomatys.fr>");
+MODULE_DESCRIPTION("adm1029 driver");
+MODULE_LICENSE("GPL v2");
+
+module_init(sensors_adm1029_init);
+module_exit(sensors_adm1029_exit);
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index a272cae..7c29734 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -146,7 +146,6 @@
 struct f71805f_data {
 	unsigned short addr;
 	const char *name;
-	struct mutex lock;
 	struct class_device *class_dev;
 
 	struct mutex update_lock;
@@ -271,50 +270,42 @@
  * Device I/O access
  */
 
+/* Must be called with data->update_lock held, except during initialization */
 static u8 f71805f_read8(struct f71805f_data *data, u8 reg)
 {
-	u8 val;
-
-	mutex_lock(&data->lock);
 	outb(reg, data->addr + ADDR_REG_OFFSET);
-	val = inb(data->addr + DATA_REG_OFFSET);
-	mutex_unlock(&data->lock);
-
-	return val;
+	return inb(data->addr + DATA_REG_OFFSET);
 }
 
+/* Must be called with data->update_lock held, except during initialization */
 static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val)
 {
-	mutex_lock(&data->lock);
 	outb(reg, data->addr + ADDR_REG_OFFSET);
 	outb(val, data->addr + DATA_REG_OFFSET);
-	mutex_unlock(&data->lock);
 }
 
 /* It is important to read the MSB first, because doing so latches the
-   value of the LSB, so we are sure both bytes belong to the same value. */
+   value of the LSB, so we are sure both bytes belong to the same value.
+   Must be called with data->update_lock held, except during initialization */
 static u16 f71805f_read16(struct f71805f_data *data, u8 reg)
 {
 	u16 val;
 
-	mutex_lock(&data->lock);
 	outb(reg, data->addr + ADDR_REG_OFFSET);
 	val = inb(data->addr + DATA_REG_OFFSET) << 8;
 	outb(++reg, data->addr + ADDR_REG_OFFSET);
 	val |= inb(data->addr + DATA_REG_OFFSET);
-	mutex_unlock(&data->lock);
 
 	return val;
 }
 
+/* Must be called with data->update_lock held, except during initialization */
 static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val)
 {
-	mutex_lock(&data->lock);
 	outb(reg, data->addr + ADDR_REG_OFFSET);
 	outb(val >> 8, data->addr + DATA_REG_OFFSET);
 	outb(++reg, data->addr + ADDR_REG_OFFSET);
 	outb(val & 0xff, data->addr + DATA_REG_OFFSET);
-	mutex_unlock(&data->lock);
 }
 
 static struct f71805f_data *f71805f_update_device(struct device *dev)
@@ -1150,7 +1141,6 @@
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 	data->addr = res->start;
-	mutex_init(&data->lock);
 	data->name = names[sio_data->kind];
 	mutex_init(&data->update_lock);
 
@@ -1300,14 +1290,11 @@
 	if (err) {
 		printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
 		       err);
-		goto exit_kfree_data;
+		goto exit_device_put;
 	}
 
 	return 0;
 
-exit_kfree_data:
-	kfree(pdev->dev.platform_data);
-	pdev->dev.platform_data = NULL;
 exit_device_put:
 	platform_device_put(pdev);
 exit:
@@ -1400,10 +1387,7 @@
 
 static void __exit f71805f_exit(void)
 {
-	kfree(pdev->dev.platform_data);
-	pdev->dev.platform_data = NULL;
 	platform_device_unregister(pdev);
-
 	platform_driver_unregister(&f71805f_driver);
 }
 
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index 106fa01..affcc00 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -101,7 +101,7 @@
 	class_destroy(hwmon_class);
 }
 
-module_init(hwmon_init);
+subsys_initcall(hwmon_init);
 module_exit(hwmon_exit);
 
 EXPORT_SYMBOL_GPL(hwmon_device_register);
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 1ed8b7e..62afc63 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -202,15 +202,23 @@
 }
 #define DIV_FROM_REG(val) (1 << (val))
 
+static const unsigned int pwm_freq[8] = {
+	48000000 / 128,
+	24000000 / 128,
+	12000000 / 128,
+	8000000 / 128,
+	6000000 / 128,
+	3000000 / 128,
+	1500000 / 128,
+	750000 / 128,
+};
 
-/* For each registered IT87, we need to keep some data in memory. That
-   data is pointed to by it87_list[NR]->data. The structure itself is
-   dynamically allocated, at the same time when a new it87 client is
-   allocated. */
+
+/* For each registered chip, we need to keep some data in memory.
+   The structure is dynamically allocated. */
 struct it87_data {
 	struct i2c_client client;
 	struct class_device *class_dev;
-	struct mutex lock;
 	enum chips type;
 
 	struct mutex update_lock;
@@ -232,6 +240,7 @@
 	u8 vrm;
 	u32 alarms;		/* Register encoding, combined */
 	u8 fan_main_ctrl;	/* Register value */
+	u8 fan_ctl;		/* Register value */
 	u8 manual_pwm_ctl[3];   /* manual PWM value set by user */
 };
 
@@ -519,6 +528,14 @@
 	struct it87_data *data = it87_update_device(dev);
 	return sprintf(buf,"%d\n", data->manual_pwm_ctl[nr]);
 }
+static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct it87_data *data = it87_update_device(dev);
+	int index = (data->fan_ctl >> 4) & 0x07;
+
+	return sprintf(buf, "%u\n", pwm_freq[index]);
+}
 static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
@@ -528,9 +545,10 @@
 	struct i2c_client *client = to_i2c_client(dev);
 	struct it87_data *data = i2c_get_clientdata(client);
 	int val = simple_strtol(buf, NULL, 10);
-	u8 reg = it87_read_value(client, IT87_REG_FAN_DIV);
+	u8 reg;
 
 	mutex_lock(&data->update_lock);
+	reg = it87_read_value(client, IT87_REG_FAN_DIV);
 	switch (nr) {
 	case 0: data->fan_div[nr] = reg & 0x07; break;
 	case 1: data->fan_div[nr] = (reg >> 3) & 0x07; break;
@@ -639,6 +657,28 @@
 	mutex_unlock(&data->update_lock);
 	return count;
 }
+static ssize_t set_pwm_freq(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct it87_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	int i;
+
+	/* Search for the nearest available frequency */
+	for (i = 0; i < 7; i++) {
+		if (val > (pwm_freq[i] + pwm_freq[i+1]) / 2)
+			break;
+	}
+
+	mutex_lock(&data->update_lock);
+	data->fan_ctl = it87_read_value(client, IT87_REG_FAN_CTL) & 0x8f;
+	data->fan_ctl |= i << 4;
+	it87_write_value(client, IT87_REG_FAN_CTL, data->fan_ctl);
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
 
 #define show_fan_offset(offset)					\
 static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,		\
@@ -656,7 +696,10 @@
 static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR,	\
 		show_pwm_enable, set_pwm_enable, offset - 1);		\
 static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR,		\
-		show_pwm, set_pwm, offset - 1);
+		show_pwm, set_pwm, offset - 1);				\
+static DEVICE_ATTR(pwm##offset##_freq,					\
+		(offset == 1 ? S_IRUGO | S_IWUSR : S_IRUGO),		\
+		show_pwm_freq, (offset == 1 ? set_pwm_freq : NULL));
 
 show_pwm_offset(1);
 show_pwm_offset(2);
@@ -904,7 +947,6 @@
 	}
 
 	new_client = &data->client;
-	mutex_init(&data->lock);
 	i2c_set_clientdata(new_client, data);
 	new_client->addr = isa_address;
 	new_client->adapter = adapter;
@@ -1021,7 +1063,13 @@
 		 || (err = device_create_file(&new_client->dev,
 		     &sensor_dev_attr_pwm2.dev_attr))
 		 || (err = device_create_file(&new_client->dev,
-		     &sensor_dev_attr_pwm3.dev_attr)))
+		     &sensor_dev_attr_pwm3.dev_attr))
+		 || (err = device_create_file(&new_client->dev,
+		     &dev_attr_pwm1_freq))
+		 || (err = device_create_file(&new_client->dev,
+		     &dev_attr_pwm2_freq))
+		 || (err = device_create_file(&new_client->dev,
+		     &dev_attr_pwm3_freq)))
 			goto ERROR4;
 	}
 
@@ -1076,33 +1124,22 @@
 	return 0;
 }
 
-/* ISA access must be locked explicitly!
+/* Must be called with data->update_lock held, except during initialization.
    We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
    would slow down the IT87 access and should not be necessary. */
 static int it87_read_value(struct i2c_client *client, u8 reg)
 {
-	struct it87_data *data = i2c_get_clientdata(client);
-	int res;
-
-	mutex_lock(&data->lock);
 	outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
-	res = inb_p(client->addr + IT87_DATA_REG_OFFSET);
-	mutex_unlock(&data->lock);
-
-	return res;
+	return inb_p(client->addr + IT87_DATA_REG_OFFSET);
 }
 
-/* ISA access must be locked explicitly!
+/* Must be called with data->update_lock held, except during initialization.
    We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
    would slow down the IT87 access and should not be necessary. */
 static void it87_write_value(struct i2c_client *client, u8 reg, u8 value)
 {
-	struct it87_data *data = i2c_get_clientdata(client);
-
-	mutex_lock(&data->lock);
 	outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
 	outb_p(value, client->addr + IT87_DATA_REG_OFFSET);
-	mutex_unlock(&data->lock);
 }
 
 /* Return 1 if and only if the PWM interface is safe to use */
@@ -1316,6 +1353,7 @@
 			(it87_read_value(client, IT87_REG_ALARM2) << 8) |
 			(it87_read_value(client, IT87_REG_ALARM3) << 16);
 		data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
+		data->fan_ctl = it87_read_value(client, IT87_REG_FAN_CTL);
 
 		data->sensor = it87_read_value(client, IT87_REG_TEMP_ENABLE);
 		/* The 8705 does not have VID capability */
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c
index 6ba8473..7eaae38 100644
--- a/drivers/hwmon/lm70.c
+++ b/drivers/hwmon/lm70.c
@@ -126,7 +126,7 @@
 	return status;
 }
 
-static int __exit lm70_remove(struct spi_device *spi)
+static int __devexit lm70_remove(struct spi_device *spi)
 {
 	struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
 
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index 73bc2ff..886786c 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -125,10 +125,8 @@
    bad. Quite a lot of bookkeeping is done. A real driver can often cut
    some corners. */
 
-/* For each registered LM78, we need to keep some data in memory. That
-   data is pointed to by lm78_list[NR]->data. The structure itself is
-   dynamically allocated, at the same time when a new lm78 client is
-   allocated. */
+/* For each registered chip, we need to keep some data in memory.
+   The structure is dynamically allocated. */
 struct lm78_data {
 	struct i2c_client client;
 	struct class_device *class_dev;
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c
index 2c3293c..20a8c64 100644
--- a/drivers/hwmon/lm85.c
+++ b/drivers/hwmon/lm85.c
@@ -298,11 +298,6 @@
 #define LM85_DATA_INTERVAL  (HZ + HZ / 2)
 #define LM85_CONFIG_INTERVAL  (1 * 60 * HZ)
 
-/* For each registered LM85, we need to keep some data in memory. That
-   data is pointed to by lm85_list[NR]->data. The structure itself is
-   dynamically allocated, at the same time when a new lm85 client is
-   allocated. */
-
 /* LM85 can automatically adjust fan speeds based on temperature
  * This structure encapsulates an entire Zone config.  There are
  * three zones (one for each temperature input) on the lm85
@@ -329,10 +324,11 @@
 	u8 min_off;	/* Min PWM or OFF below "limit", flag */
 };
 
+/* For each registered chip, we need to keep some data in memory.
+   The structure is dynamically allocated. */
 struct lm85_data {
 	struct i2c_client client;
 	struct class_device *class_dev;
-	struct mutex lock;
 	enum chips type;
 
 	struct mutex update_lock;
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index 95a4b5d..3f40026 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -162,10 +162,8 @@
 }
 #define DIV_FROM_REG(val) (1 << (val))
 
-/* For the SIS5595, we need to keep some data in memory. That
-   data is pointed to by sis5595_list[NR]->data. The structure itself is
-   dynamically allocated, at the time when the new sis5595 client is
-   allocated. */
+/* For each registered chip, we need to keep some data in memory.
+   The structure is dynamically allocated. */
 struct sis5595_data {
 	struct i2c_client client;
 	struct class_device *class_dev;
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index f8acada..9a440c8 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -292,9 +292,8 @@
 #define DIV_FROM_REG(val) (1 << (val))
 #define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
 
-/* For the VIA686A, we need to keep some data in memory.
-   The structure is dynamically allocated, at the same time when a new
-   via686a client is allocated. */
+/* For each registered chip, we need to keep some data in memory.
+   The structure is dynamically allocated. */
 struct via686a_data {
 	struct i2c_client client;
 	struct class_device *class_dev;
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index 25cc560..89c23d6 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -178,9 +178,10 @@
  * Super-I/O constants and functions
  * --------------------------------------------------------------------- */
 
-/* Configuration & data index port registers */
-#define SIO_REG_CIP		0x2e
-#define SIO_REG_DIP		0x2f
+/* Configuration index port registers
+ * The vt1211 can live at 2 different addresses so we need to probe both */
+#define SIO_REG_CIP1		0x2e
+#define SIO_REG_CIP2		0x4e
 
 /* Configuration registers */
 #define SIO_VT1211_LDN		0x07	/* logical device number */
@@ -193,33 +194,33 @@
 /* VT1211 logical device numbers */
 #define SIO_VT1211_LDN_HWMON	0x0b	/* HW monitor */
 
-static inline void superio_outb(int reg, int val)
+static inline void superio_outb(int sio_cip, int reg, int val)
 {
-	outb(reg, SIO_REG_CIP);
-	outb(val, SIO_REG_DIP);
+	outb(reg, sio_cip);
+	outb(val, sio_cip + 1);
 }
 
-static inline int superio_inb(int reg)
+static inline int superio_inb(int sio_cip, int reg)
 {
-	outb(reg, SIO_REG_CIP);
-	return inb(SIO_REG_DIP);
+	outb(reg, sio_cip);
+	return inb(sio_cip + 1);
 }
 
-static inline void superio_select(int ldn)
+static inline void superio_select(int sio_cip, int ldn)
 {
-	outb(SIO_VT1211_LDN, SIO_REG_CIP);
-	outb(ldn, SIO_REG_DIP);
+	outb(SIO_VT1211_LDN, sio_cip);
+	outb(ldn, sio_cip + 1);
 }
 
-static inline void superio_enter(void)
+static inline void superio_enter(int sio_cip)
 {
-	outb(0x87, SIO_REG_CIP);
-	outb(0x87, SIO_REG_CIP);
+	outb(0x87, sio_cip);
+	outb(0x87, sio_cip);
 }
 
-static inline void superio_exit(void)
+static inline void superio_exit(int sio_cip)
 {
-	outb(0xaa, SIO_REG_CIP);
+	outb(0xaa, sio_cip);
 }
 
 /* ---------------------------------------------------------------------
@@ -1263,26 +1264,26 @@
 	return err;
 }
 
-static int __init vt1211_find(unsigned short *address)
+static int __init vt1211_find(int sio_cip, unsigned short *address)
 {
 	int err = -ENODEV;
 
-	superio_enter();
+	superio_enter(sio_cip);
 
-	if (superio_inb(SIO_VT1211_DEVID) != SIO_VT1211_ID) {
+	if (superio_inb(sio_cip, SIO_VT1211_DEVID) != SIO_VT1211_ID) {
 		goto EXIT;
 	}
 
-	superio_select(SIO_VT1211_LDN_HWMON);
+	superio_select(sio_cip, SIO_VT1211_LDN_HWMON);
 
-	if ((superio_inb(SIO_VT1211_ACTIVE) & 1) == 0) {
+	if ((superio_inb(sio_cip, SIO_VT1211_ACTIVE) & 1) == 0) {
 		printk(KERN_WARNING DRVNAME ": HW monitor is disabled, "
 		       "skipping\n");
 		goto EXIT;
 	}
 
-	*address = ((superio_inb(SIO_VT1211_BADDR) << 8) |
-		    (superio_inb(SIO_VT1211_BADDR + 1))) & 0xff00;
+	*address = ((superio_inb(sio_cip, SIO_VT1211_BADDR) << 8) |
+		    (superio_inb(sio_cip, SIO_VT1211_BADDR + 1))) & 0xff00;
 	if (*address == 0) {
 		printk(KERN_WARNING DRVNAME ": Base address is not set, "
 		       "skipping\n");
@@ -1291,10 +1292,11 @@
 
 	err = 0;
 	printk(KERN_INFO DRVNAME ": Found VT1211 chip at 0x%04x, "
-	       "revision %u\n", *address, superio_inb(SIO_VT1211_DEVREV));
+	       "revision %u\n", *address,
+	       superio_inb(sio_cip, SIO_VT1211_DEVREV));
 
 EXIT:
-	superio_exit();
+	superio_exit(sio_cip);
 	return err;
 }
 
@@ -1303,8 +1305,8 @@
 	int err;
 	unsigned short address = 0;
 
-	err = vt1211_find(&address);
-	if (err) {
+	if ((err = vt1211_find(SIO_REG_CIP1, &address)) &&
+	    (err = vt1211_find(SIO_REG_CIP2, &address))) {
 		goto EXIT;
 	}
 
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 212a155..da5828f 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -32,8 +32,10 @@
 
     Supports the following chips:
 
-    Chip        #vin    #fan    #pwm    #temp   chip_id    man_id
-    w83627ehf   10      5       4       3       0x88,0xa1  0x5ca3
+    Chip        #vin    #fan    #pwm    #temp  chip IDs       man ID
+    w83627ehf   10      5       4       3      0x8850 0x88    0x5ca3
+                                               0x8860 0xa1
+    w83627dhg    9      5       4       3      0xa020 0xc1    0x5ca3
 */
 
 #include <linux/module.h>
@@ -55,8 +57,18 @@
  * Super-I/O constants and functions
  */
 
+/*
+ * The three following globals are initialized in w83627ehf_find(), before
+ * the i2c-isa device is created. Otherwise, they could be stored in
+ * w83627ehf_data. This is ugly, but necessary, and when the driver is next
+ * updated to become a platform driver, the globals will disappear.
+ */
 static int REG;		/* The register to read/write */
 static int VAL;		/* The value to read/write */
+/* The w83627ehf/ehg have 10 voltage inputs, but the w83627dhg has 9. This
+ * value is also used in w83627ehf_detect() to export a device name in sysfs
+ * (e.g. w83627ehf or w83627dhg) */
+static int w83627ehf_num_in;
 
 #define W83627EHF_LD_HWM	0x0b
 
@@ -65,8 +77,10 @@
 #define SIO_REG_ENABLE		0x30	/* Logical device enable */
 #define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
 
-#define SIO_W83627EHF_ID	0x8840
-#define SIO_ID_MASK		0xFFC0
+#define SIO_W83627EHF_ID	0x8850
+#define SIO_W83627EHG_ID	0x8860
+#define SIO_W83627DHG_ID	0xa020
+#define SIO_ID_MASK		0xFFF0
 
 static inline void
 superio_outb(int reg, int val)
@@ -115,8 +129,12 @@
 
 #define W83627EHF_REG_BANK		0x4E
 #define W83627EHF_REG_CONFIG		0x40
-#define W83627EHF_REG_CHIP_ID		0x49
-#define W83627EHF_REG_MAN_ID		0x4F
+
+/* Not currently used:
+ * REG_MAN_ID has the value 0x5ca3 for all supported chips.
+ * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model.
+ * REG_MAN_ID is at port 0x4f
+ * REG_CHIP_ID is at port 0x58 */
 
 static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 };
 static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c };
@@ -429,7 +447,7 @@
 		}
 
 		/* Measured voltages and limits */
-		for (i = 0; i < 10; i++) {
+		for (i = 0; i < w83627ehf_num_in; i++) {
 			data->in[i] = w83627ehf_read_value(client,
 				      W83627EHF_REG_IN(i));
 			data->in_min[i] = w83627ehf_read_value(client,
@@ -1121,7 +1139,7 @@
 		device_remove_file(dev, &sda_sf3_arrays[i].dev_attr);
 	for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++)
 		device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr);
-	for (i = 0; i < 10; i++) {
+	for (i = 0; i < w83627ehf_num_in; i++) {
 		device_remove_file(dev, &sda_in_input[i].dev_attr);
 		device_remove_file(dev, &sda_in_alarm[i].dev_attr);
 		device_remove_file(dev, &sda_in_min[i].dev_attr);
@@ -1196,7 +1214,11 @@
 	client->flags = 0;
 	dev = &client->dev;
 
-	strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE);
+	if (w83627ehf_num_in == 9)
+		strlcpy(client->name, "w83627dhg", I2C_NAME_SIZE);
+	else	/* just say ehf. 627EHG is 627EHF in lead-free packaging. */
+		strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE);
+
 	data->valid = 0;
 	mutex_init(&data->update_lock);
 
@@ -1246,7 +1268,7 @@
 				goto exit_remove;
 		}
 
-	for (i = 0; i < 10; i++)
+	for (i = 0; i < w83627ehf_num_in; i++)
 		if ((err = device_create_file(dev, &sda_in_input[i].dev_attr))
 			|| (err = device_create_file(dev,
 				&sda_in_alarm[i].dev_attr))
@@ -1340,7 +1362,17 @@
 
 	val = (superio_inb(SIO_REG_DEVID) << 8)
 	    | superio_inb(SIO_REG_DEVID + 1);
-	if ((val & SIO_ID_MASK) != SIO_W83627EHF_ID) {
+	switch (val & SIO_ID_MASK) {
+	case SIO_W83627DHG_ID:
+		w83627ehf_num_in = 9;
+		break;
+	case SIO_W83627EHF_ID:
+	case SIO_W83627EHG_ID:
+		w83627ehf_num_in = 10;
+		break;
+	default:
+		printk(KERN_WARNING "w83627ehf: unsupported chip ID: 0x%04x\n",
+			val);
 		superio_exit();
 		return -ENODEV;
 	}
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index dfdc29c7..d7e2406 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -286,9 +286,8 @@
 	return ((u8) i);
 }
 
-/* For each registered chip, we need to keep some data in memory. That
-   data is pointed to by w83627hf_list[NR]->data. The structure itself is
-   dynamically allocated, at the same time when a new client is allocated. */
+/* For each registered chip, we need to keep some data in memory.
+   The structure is dynamically allocated. */
 struct w83627hf_data {
 	struct i2c_client client;
 	struct class_device *class_dev;
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index 1232171..a47da3e 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -221,14 +221,8 @@
    a bit - except if there could be more than one SMBus. Groan. No solution
    for this yet. */
 
-/* This module may seem overly long and complicated. In fact, it is not so
-   bad. Quite a lot of bookkeeping is done. A real driver can often cut
-   some corners. */
-
-/* For each registered W83781D, we need to keep some data in memory. That
-   data is pointed to by w83781d_list[NR]->data. The structure itself is
-   dynamically allocated, at the same time when a new w83781d client is
-   allocated. */
+/* For each registered chip, we need to keep some data in memory.
+   The structure is dynamically allocated. */
 struct w83781d_data {
 	struct i2c_client client;
 	struct class_device *class_dev;
diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
index 6fd8ad7..1e277ba 100644
--- a/drivers/i2c/busses/i2c-ali1535.c
+++ b/drivers/i2c/busses/i2c-ali1535.c
@@ -494,7 +494,7 @@
 		return -ENODEV;
 	}
 
-	/* set up the driverfs linkage to our parent device */
+	/* set up the sysfs linkage to our parent device */
 	ali1535_adapter.dev.parent = &dev->dev;
 
 	snprintf(ali1535_adapter.name, I2C_NAME_SIZE, 
diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
index e4e0df1..e47fe01 100644
--- a/drivers/i2c/busses/i2c-ali15x3.c
+++ b/drivers/i2c/busses/i2c-ali15x3.c
@@ -489,7 +489,7 @@
 		return -ENODEV;
 	}
 
-	/* set up the driverfs linkage to our parent device */
+	/* set up the sysfs linkage to our parent device */
 	ali15x3_adapter.dev.parent = &dev->dev;
 
 	snprintf(ali15x3_adapter.name, I2C_NAME_SIZE,
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
index fa6155a..7490dc1 100644
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -374,7 +374,7 @@
 	dev_dbg(&pdev->dev, "SMBREV = 0x%X\n", temp);
 	dev_dbg(&pdev->dev, "AMD756_smba = 0x%X\n", amd756_ioport);
 
-	/* set up the driverfs linkage to our parent device */
+	/* set up the sysfs linkage to our parent device */
 	amd756_smbus.dev.parent = &pdev->dev;
 
 	sprintf(amd756_smbus.name, "SMBus %s adapter at %04x",
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
index 5bba3fb..e15f9e3 100644
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -371,7 +371,7 @@
 	smbus->adapter.algo = &smbus_algorithm;
 	smbus->adapter.algo_data = smbus;
 
-	/* set up the driverfs linkage to our parent device */
+	/* set up the sysfs linkage to our parent device */
 	smbus->adapter.dev.parent = &dev->dev;
 
 	pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0);
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 21f2671..6569a36 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -522,7 +522,7 @@
 	else
 		dev_dbg(&dev->dev, "SMBus using PCI Interrupt\n");
 
-	/* set up the driverfs linkage to our parent device */
+	/* set up the sysfs linkage to our parent device */
 	i801_adapter.dev.parent = &dev->dev;
 
 	snprintf(i801_adapter.name, I2C_NAME_SIZE,
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index 20ee4f7..90e2d93 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -83,7 +83,7 @@
 	 * Every time unit enable is asserted, GPOD needs to be cleared
 	 * on IOP3XX to avoid data corruption on the bus.
 	 */
-#ifdef CONFIG_PLAT_IOP
+#if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X)
 	if (iop3xx_adap->id == 0) {
 		gpio_line_set(IOP3XX_GPIO_LINE(7), GPIO_LOW);
 		gpio_line_set(IOP3XX_GPIO_LINE(6), GPIO_LOW);
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index d888293..21b1809 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -425,7 +425,7 @@
 	if (retval)
 		return retval;
 
-	/* set up the driverfs linkage to our parent device */
+	/* set up the sysfs linkage to our parent device */
 	piix4_adapter.dev.parent = &dev->dev;
 
 	snprintf(piix4_adapter.name, I2C_NAME_SIZE,
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index c3b1567..14e83d0 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -34,6 +34,7 @@
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
+#include <asm/io.h>
 #include <asm/arch/i2c.h>
 #include <asm/arch/pxa-regs.h>
 
@@ -54,8 +55,21 @@
 	unsigned int		irqlogidx;
 	u32			isrlog[32];
 	u32			icrlog[32];
+
+	void __iomem		*reg_base;
+
+	unsigned long		iobase;
+	unsigned long		iosize;
+
+	int			irq;
 };
 
+#define _IBMR(i2c)	((i2c)->reg_base + 0)
+#define _IDBR(i2c)	((i2c)->reg_base + 8)
+#define _ICR(i2c)	((i2c)->reg_base + 0x10)
+#define _ISR(i2c)	((i2c)->reg_base + 0x18)
+#define _ISAR(i2c)	((i2c)->reg_base + 0x20)
+
 /*
  * I2C Slave mode address
  */
@@ -130,7 +144,8 @@
 
 static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname)
 {
-	dev_dbg(&i2c->adap.dev, "state:%s:%d: ISR=%08x, ICR=%08x, IBMR=%02x\n", fname, lno, ISR, ICR, IBMR);
+	dev_dbg(&i2c->adap.dev, "state:%s:%d: ISR=%08x, ICR=%08x, IBMR=%02x\n", fname, lno,
+		readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
 }
 
 #define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __FUNCTION__)
@@ -153,7 +168,7 @@
 	printk("i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
 		i2c->msg_num, i2c->msg_idx, i2c->msg_ptr);
 	printk("i2c: ICR: %08x ISR: %08x\n"
-	       "i2c: log: ", ICR, ISR);
+	       "i2c: log: ", readl(_ICR(i2c)), readl(_ISR(i2c)));
 	for (i = 0; i < i2c->irqlogidx; i++)
 		printk("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]);
 	printk("\n");
@@ -161,7 +176,7 @@
 
 static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c)
 {
-	return !(ICR & ICR_SCLE);
+	return !(readl(_ICR(i2c)) & ICR_SCLE);
 }
 
 static void i2c_pxa_abort(struct pxa_i2c *i2c)
@@ -173,28 +188,29 @@
 		return;
 	}
 
-	while (time_before(jiffies, timeout) && (IBMR & 0x1) == 0) {
-		unsigned long icr = ICR;
+	while (time_before(jiffies, timeout) && (readl(_IBMR(i2c)) & 0x1) == 0) {
+		unsigned long icr = readl(_ICR(i2c));
 
 		icr &= ~ICR_START;
 		icr |= ICR_ACKNAK | ICR_STOP | ICR_TB;
 
-		ICR = icr;
+		writel(icr, _ICR(i2c));
 
 		show_state(i2c);
 
 		msleep(1);
 	}
 
-	ICR &= ~(ICR_MA | ICR_START | ICR_STOP);
+	writel(readl(_ICR(i2c)) & ~(ICR_MA | ICR_START | ICR_STOP),
+	       _ICR(i2c));
 }
 
 static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c)
 {
 	int timeout = DEF_TIMEOUT;
 
-	while (timeout-- && ISR & (ISR_IBB | ISR_UB)) {
-		if ((ISR & ISR_SAD) != 0)
+	while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB)) {
+		if ((readl(_ISR(i2c)) & ISR_SAD) != 0)
 			timeout += 4;
 
 		msleep(2);
@@ -214,9 +230,9 @@
 	while (time_before(jiffies, timeout)) {
 		if (i2c_debug > 1)
 			dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
-				__func__, (long)jiffies, ISR, ICR, IBMR);
+				__func__, (long)jiffies, readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
 
-		if (ISR & ISR_SAD) {
+		if (readl(_ISR(i2c)) & ISR_SAD) {
 			if (i2c_debug > 0)
 				dev_dbg(&i2c->adap.dev, "%s: Slave detected\n", __func__);
 			goto out;
@@ -226,7 +242,7 @@
 		 * quick check of the i2c lines themselves to ensure they've
 		 * gone high...
 		 */
-		if ((ISR & (ISR_UB | ISR_IBB)) == 0 && IBMR == 3) {
+		if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) == 0 && readl(_IBMR(i2c)) == 3) {
 			if (i2c_debug > 0)
 				dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
 			return 1;
@@ -246,7 +262,7 @@
 	if (i2c_debug)
 		dev_dbg(&i2c->adap.dev, "setting to bus master\n");
 
-	if ((ISR & (ISR_UB | ISR_IBB)) != 0) {
+	if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) != 0) {
 		dev_dbg(&i2c->adap.dev, "%s: unit is busy\n", __func__);
 		if (!i2c_pxa_wait_master(i2c)) {
 			dev_dbg(&i2c->adap.dev, "%s: error: unit busy\n", __func__);
@@ -254,7 +270,7 @@
 		}
 	}
 
-	ICR |= ICR_SCLE;
+	writel(readl(_ICR(i2c)) | ICR_SCLE, _ICR(i2c));
 	return 0;
 }
 
@@ -270,11 +286,11 @@
 	while (time_before(jiffies, timeout)) {
 		if (i2c_debug > 1)
 			dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
-				__func__, (long)jiffies, ISR, ICR, IBMR);
+				__func__, (long)jiffies, readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
 
-		if ((ISR & (ISR_UB|ISR_IBB)) == 0 ||
-		    (ISR & ISR_SAD) != 0 ||
-		    (ICR & ICR_SCLE) == 0) {
+		if ((readl(_ISR(i2c)) & (ISR_UB|ISR_IBB)) == 0 ||
+		    (readl(_ISR(i2c)) & ISR_SAD) != 0 ||
+		    (readl(_ICR(i2c)) & ICR_SCLE) == 0) {
 			if (i2c_debug > 1)
 				dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
 			return 1;
@@ -302,9 +318,9 @@
 		/* we need to wait for the stop condition to end */
 
 		/* if we where in stop, then clear... */
-		if (ICR & ICR_STOP) {
+		if (readl(_ICR(i2c)) & ICR_STOP) {
 			udelay(100);
-			ICR &= ~ICR_STOP;
+			writel(readl(_ICR(i2c)) & ~ICR_STOP, _ICR(i2c));
 		}
 
 		if (!i2c_pxa_wait_slave(i2c)) {
@@ -314,12 +330,12 @@
 		}
 	}
 
-	ICR &= ~(ICR_STOP|ICR_ACKNAK|ICR_MA);
-	ICR &= ~ICR_SCLE;
+	writel(readl(_ICR(i2c)) & ~(ICR_STOP|ICR_ACKNAK|ICR_MA), _ICR(i2c));
+	writel(readl(_ICR(i2c)) & ~ICR_SCLE, _ICR(i2c));
 
 	if (i2c_debug) {
-		dev_dbg(&i2c->adap.dev, "ICR now %08x, ISR %08x\n", ICR, ISR);
-		decode_ICR(ICR);
+		dev_dbg(&i2c->adap.dev, "ICR now %08x, ISR %08x\n", readl(_ICR(i2c)), readl(_ISR(i2c)));
+		decode_ICR(readl(_ICR(i2c)));
 	}
 }
 #else
@@ -334,24 +350,24 @@
 	i2c_pxa_abort(i2c);
 
 	/* reset according to 9.8 */
-	ICR = ICR_UR;
-	ISR = I2C_ISR_INIT;
-	ICR &= ~ICR_UR;
+	writel(ICR_UR, _ICR(i2c));
+	writel(I2C_ISR_INIT, _ISR(i2c));
+	writel(readl(_ICR(i2c)) & ~ICR_UR, _ICR(i2c));
 
-	ISAR = i2c->slave_addr;
+	writel(i2c->slave_addr, _ISAR(i2c));
 
 	/* set control register values */
-	ICR = I2C_ICR_INIT;
+	writel(I2C_ICR_INIT, _ICR(i2c));
 
 #ifdef CONFIG_I2C_PXA_SLAVE
 	dev_info(&i2c->adap.dev, "Enabling slave mode\n");
-	ICR |= ICR_SADIE | ICR_ALDIE | ICR_SSDIE;
+	writel(readl(_ICR(i2c)) | ICR_SADIE | ICR_ALDIE | ICR_SSDIE, _ICR(i2c));
 #endif
 
 	i2c_pxa_set_slave(i2c, 0);
 
 	/* enable unit */
-	ICR |= ICR_IUE;
+	writel(readl(_ICR(i2c)) | ICR_IUE, _ICR(i2c));
 	udelay(100);
 }
 
@@ -371,19 +387,19 @@
 		if (i2c->slave != NULL)
 			ret = i2c->slave->read(i2c->slave->data);
 
-		IDBR = ret;
-		ICR |= ICR_TB;   /* allow next byte */
+		writel(ret, _IDBR(i2c));
+		writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));   /* allow next byte */
 	}
 }
 
 static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
 {
-	unsigned int byte = IDBR;
+	unsigned int byte = readl(_IDBR(i2c));
 
 	if (i2c->slave != NULL)
 		i2c->slave->write(i2c->slave->data, byte);
 
-	ICR |= ICR_TB;
+	writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));
 }
 
 static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
@@ -403,13 +419,13 @@
 	 * start condition... if this happens, we'd better back off
 	 * and stop holding the poor thing up
 	 */
-	ICR &= ~(ICR_START|ICR_STOP);
-	ICR |= ICR_TB;
+	writel(readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP), _ICR(i2c));
+	writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));
 
 	timeout = 0x10000;
 
 	while (1) {
-		if ((IBMR & 2) == 2)
+		if ((readl(_IBMR(i2c)) & 2) == 2)
 			break;
 
 		timeout--;
@@ -420,7 +436,7 @@
 		}
 	}
 
-	ICR &= ~ICR_SCLE;
+	writel(readl(_ICR(i2c)) & ~ICR_SCLE, _ICR(i2c));
 }
 
 static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
@@ -447,14 +463,14 @@
 	if (isr & ISR_BED) {
 		/* what should we do here? */
 	} else {
-		IDBR = 0;
-		ICR |= ICR_TB;
+		writel(0, _IDBR(i2c));
+		writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));
 	}
 }
 
 static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
 {
-	ICR |= ICR_TB | ICR_ACKNAK;
+	writel(readl(_ICR(i2c)) | ICR_TB | ICR_ACKNAK, _ICR(i2c));
 }
 
 static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
@@ -466,13 +482,13 @@
 	 * start condition... if this happens, we'd better back off
 	 * and stop holding the poor thing up
 	 */
-	ICR &= ~(ICR_START|ICR_STOP);
-	ICR |= ICR_TB | ICR_ACKNAK;
+	writel(readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP), _ICR(i2c));
+	writel(readl(_ICR(i2c)) | ICR_TB | ICR_ACKNAK, _ICR(i2c));
 
 	timeout = 0x10000;
 
 	while (1) {
-		if ((IBMR & 2) == 2)
+		if ((readl(_IBMR(i2c)) & 2) == 2)
 			break;
 
 		timeout--;
@@ -483,7 +499,7 @@
 		}
 	}
 
-	ICR &= ~ICR_SCLE;
+	writel(readl(_ICR(i2c)) & ~ICR_SCLE, _ICR(i2c));
 }
 
 static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
@@ -514,13 +530,13 @@
 	/*
 	 * Step 1: target slave address into IDBR
 	 */
-	IDBR = i2c_pxa_addr_byte(i2c->msg);
+	writel(i2c_pxa_addr_byte(i2c->msg), _IDBR(i2c));
 
 	/*
 	 * Step 2: initiate the write.
 	 */
-	icr = ICR & ~(ICR_STOP | ICR_ALDIE);
-	ICR = icr | ICR_START | ICR_TB;
+	icr = readl(_ICR(i2c)) & ~(ICR_STOP | ICR_ALDIE);
+	writel(icr | ICR_START | ICR_TB, _ICR(i2c));
 }
 
 /*
@@ -594,7 +610,7 @@
 
 static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
 {
-	u32 icr = ICR & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
+	u32 icr = readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
 
  again:
 	/*
@@ -645,7 +661,7 @@
 		/*
 		 * Write mode.  Write the next data byte.
 		 */
-		IDBR = i2c->msg->buf[i2c->msg_ptr++];
+		writel(i2c->msg->buf[i2c->msg_ptr++], _IDBR(i2c));
 
 		icr |= ICR_ALDIE | ICR_TB;
 
@@ -675,7 +691,7 @@
 		/*
 		 * Write the next address.
 		 */
-		IDBR = i2c_pxa_addr_byte(i2c->msg);
+		writel(i2c_pxa_addr_byte(i2c->msg), _IDBR(i2c));
 
 		/*
 		 * And trigger a repeated start, and send the byte.
@@ -696,18 +712,18 @@
 
 	i2c->icrlog[i2c->irqlogidx-1] = icr;
 
-	ICR = icr;
+	writel(icr, _ICR(i2c));
 	show_state(i2c);
 }
 
 static void i2c_pxa_irq_rxfull(struct pxa_i2c *i2c, u32 isr)
 {
-	u32 icr = ICR & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
+	u32 icr = readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
 
 	/*
 	 * Read the byte.
 	 */
-	i2c->msg->buf[i2c->msg_ptr++] = IDBR;
+	i2c->msg->buf[i2c->msg_ptr++] = readl(_IDBR(i2c));
 
 	if (i2c->msg_ptr < i2c->msg->len) {
 		/*
@@ -724,17 +740,17 @@
 
 	i2c->icrlog[i2c->irqlogidx-1] = icr;
 
-	ICR = icr;
+	writel(icr, _ICR(i2c));
 }
 
 static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
 {
 	struct pxa_i2c *i2c = dev_id;
-	u32 isr = ISR;
+	u32 isr = readl(_ISR(i2c));
 
 	if (i2c_debug > 2 && 0) {
 		dev_dbg(&i2c->adap.dev, "%s: ISR=%08x, ICR=%08x, IBMR=%02x\n",
-			__func__, isr, ICR, IBMR);
+			__func__, isr, readl(_ICR(i2c)), readl(_IBMR(i2c)));
 		decode_ISR(isr);
 	}
 
@@ -746,7 +762,7 @@
 	/*
 	 * Always clear all pending IRQs.
 	 */
-	ISR = isr & (ISR_SSD|ISR_ALD|ISR_ITE|ISR_IRF|ISR_SAD|ISR_BED);
+	writel(isr & (ISR_SSD|ISR_ALD|ISR_ITE|ISR_IRF|ISR_SAD|ISR_BED), _ISR(i2c));
 
 	if (isr & ISR_SAD)
 		i2c_pxa_slave_start(i2c, isr);
@@ -779,7 +795,7 @@
 	/* If the I2C controller is disabled we need to reset it (probably due
  	   to a suspend/resume destroying state). We do this here as we can then
  	   avoid worrying about resuming the controller before its users. */
-	if (!(ICR & ICR_IUE))
+	if (!(readl(_ICR(i2c)) & ICR_IUE))
 		i2c_pxa_reset(i2c);
 
 	for (i = adap->retries; i >= 0; i--) {
@@ -810,28 +826,53 @@
 
 static struct pxa_i2c i2c_pxa = {
 	.lock	= SPIN_LOCK_UNLOCKED,
-	.wait	= __WAIT_QUEUE_HEAD_INITIALIZER(i2c_pxa.wait),
 	.adap	= {
 		.owner		= THIS_MODULE,
 		.algo		= &i2c_pxa_algorithm,
-		.name		= "pxa2xx-i2c",
+		.name		= "pxa2xx-i2c.0",
 		.retries	= 5,
 	},
 };
 
+#define res_len(r)		((r)->end - (r)->start + 1)
 static int i2c_pxa_probe(struct platform_device *dev)
 {
 	struct pxa_i2c *i2c = &i2c_pxa;
+	struct resource *res;
 #ifdef CONFIG_I2C_PXA_SLAVE
 	struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
 #endif
 	int ret;
+	int irq;
 
-#ifdef CONFIG_PXA27x
-	pxa_gpio_mode(GPIO117_I2CSCL_MD);
-	pxa_gpio_mode(GPIO118_I2CSDA_MD);
-	udelay(100);
-#endif
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(dev, 0);
+	if (res == NULL || irq < 0)
+		return -ENODEV;
+
+	if (!request_mem_region(res->start, res_len(res), res->name))
+		return -ENOMEM;
+
+	i2c = kmalloc(sizeof(struct pxa_i2c), GFP_KERNEL);
+	if (!i2c) {
+		ret = -ENOMEM;
+		goto emalloc;
+	}
+
+	memcpy(i2c, &i2c_pxa, sizeof(struct pxa_i2c));
+	init_waitqueue_head(&i2c->wait);
+	i2c->adap.name[strlen(i2c->adap.name) - 1] = '0' + dev->id % 10;
+
+	i2c->reg_base = ioremap(res->start, res_len(res));
+	if (!i2c->reg_base) {
+		ret = -EIO;
+		goto eremap;
+	}
+
+	i2c->iobase = res->start;
+	i2c->iosize = res_len(res);
+
+	i2c->irq = irq;
 
 	i2c->slave_addr = I2C_PXA_SLAVE_ADDR;
 
@@ -842,11 +883,28 @@
 	}
 #endif
 
-	pxa_set_cken(CKEN14_I2C, 1);
-	ret = request_irq(IRQ_I2C, i2c_pxa_handler, IRQF_DISABLED,
-			  "pxa2xx-i2c", i2c);
+	switch (dev->id) {
+	case 0:
+#ifdef CONFIG_PXA27x
+		pxa_gpio_mode(GPIO117_I2CSCL_MD);
+		pxa_gpio_mode(GPIO118_I2CSDA_MD);
+#endif
+		pxa_set_cken(CKEN14_I2C, 1);
+		break;
+#ifdef CONFIG_PXA27x
+	case 1:
+		local_irq_disable();
+		PCFR |= PCFR_PI2CEN;
+		local_irq_enable();
+		pxa_set_cken(CKEN15_PWRI2C, 1);
+#endif
+	}
+
+	ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED,
+			  i2c->adap.name, i2c);
 	if (ret)
-		goto out;
+		goto ereqirq;
+
 
 	i2c_pxa_reset(i2c);
 
@@ -856,7 +914,7 @@
 	ret = i2c_add_adapter(&i2c->adap);
 	if (ret < 0) {
 		printk(KERN_INFO "I2C: Failed to add bus\n");
-		goto err_irq;
+		goto eadapt;
 	}
 
 	platform_set_drvdata(dev, i2c);
@@ -870,9 +928,25 @@
 #endif
 	return 0;
 
- err_irq:
-	free_irq(IRQ_I2C, i2c);
- out:
+eadapt:
+	free_irq(irq, i2c);
+ereqirq:
+	switch (dev->id) {
+	case 0:
+		pxa_set_cken(CKEN14_I2C, 0);
+		break;
+#ifdef CONFIG_PXA27x
+	case 1:
+		pxa_set_cken(CKEN15_PWRI2C, 0);
+		local_irq_disable();
+		PCFR &= ~PCFR_PI2CEN;
+		local_irq_enable();
+#endif
+	}
+eremap:
+	kfree(i2c);
+emalloc:
+	release_mem_region(res->start, res_len(res));
 	return ret;
 }
 
@@ -883,8 +957,21 @@
 	platform_set_drvdata(dev, NULL);
 
 	i2c_del_adapter(&i2c->adap);
-	free_irq(IRQ_I2C, i2c);
-	pxa_set_cken(CKEN14_I2C, 0);
+	free_irq(i2c->irq, i2c);
+	switch (dev->id) {
+	case 0:
+		pxa_set_cken(CKEN14_I2C, 0);
+		break;
+#ifdef CONFIG_PXA27x
+	case 1:
+		pxa_set_cken(CKEN15_PWRI2C, 0);
+		local_irq_disable();
+		PCFR &= ~PCFR_PI2CEN;
+		local_irq_enable();
+#endif
+	}
+	release_mem_region(i2c->iobase, i2c->iosize);
+	kfree(i2c);
 
 	return 0;
 }
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
index d333bab..a6feed4 100644
--- a/drivers/i2c/busses/i2c-sis5595.c
+++ b/drivers/i2c/busses/i2c-sis5595.c
@@ -384,7 +384,7 @@
 		return -ENODEV;
 	}
 
-	/* set up the driverfs linkage to our parent device */
+	/* set up the sysfs linkage to our parent device */
 	sis5595_adapter.dev.parent = &dev->dev;
 
 	sprintf(sis5595_adapter.name, "SMBus SIS5595 adapter at %04x",
diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
index 172bacf..5fd734f 100644
--- a/drivers/i2c/busses/i2c-sis630.c
+++ b/drivers/i2c/busses/i2c-sis630.c
@@ -477,7 +477,7 @@
 		return -ENODEV;
 	}
 
-	/* set up the driverfs linkage to our parent device */
+	/* set up the sysfs linkage to our parent device */
 	sis630_adapter.dev.parent = &dev->dev;
 
 	sprintf(sis630_adapter.name, "SMBus SIS630 adapter at %04x",
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
index 73dae44..4157b0c 100644
--- a/drivers/i2c/busses/i2c-sis96x.c
+++ b/drivers/i2c/busses/i2c-sis96x.c
@@ -297,7 +297,7 @@
 		return -EINVAL;
 	}
 
-	/* set up the driverfs linkage to our parent device */
+	/* set up the sysfs linkage to our parent device */
 	sis96x_adapter.dev.parent = &dev->dev;
 
 	snprintf(sis96x_adapter.name, I2C_NAME_SIZE,
diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
index bbcc621..8152086 100644
--- a/drivers/i2c/busses/i2c-via.c
+++ b/drivers/i2c/busses/i2c-via.c
@@ -138,7 +138,7 @@
 	outb(inb(I2C_DIR) & ~(I2C_SDA | I2C_SCL), I2C_DIR);
 	outb(inb(I2C_OUT) & ~(I2C_SDA | I2C_SCL), I2C_OUT);
 
-	/* set up the driverfs linkage to our parent device */
+	/* set up the sysfs linkage to our parent device */
 	vt586b_adapter.dev.parent = &dev->dev;
 
 	res = i2c_bit_add_bus(&vt586b_adapter);
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index ec03341..49234e3 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -383,6 +383,9 @@
 config BLK_DEV_GENERIC
 	tristate "Generic PCI IDE Chipset Support"
 	depends on BLK_DEV_IDEPCI
+        help
+          This option provides generic support for various PCI IDE Chipsets
+          which otherwise might not be supported.
 
 config BLK_DEV_OPTI621
 	tristate "OPTi 82C621 chipset enhanced support (EXPERIMENTAL)"
@@ -797,6 +800,14 @@
 	  to transfer data to and from memory.  Saying Y is safe and improves
 	  performance.
 
+config BLK_DEV_IDE_CELLEB
+	bool "Toshiba's Cell Reference Set IDE support"
+	depends on PPC_CELLEB
+	help
+	  This driver provides support for the built-in IDE controller on
+	  Toshiba Cell Reference Board.
+	  If unsure, say Y.
+
 config BLK_DEV_IDE_SWARM
 	tristate "IDE for Sibyte evaluation boards"
 	depends on SIBYTE_SB1xxx_SOC
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index d9f029e..28feedf 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -37,6 +37,7 @@
 # built-in only drivers from ppc/
 ide-core-$(CONFIG_BLK_DEV_MPC8xx_IDE)	+= ppc/mpc8xx.o
 ide-core-$(CONFIG_BLK_DEV_IDE_PMAC)	+= ppc/pmac.o
+ide-core-$(CONFIG_BLK_DEV_IDE_CELLEB)	+= ppc/scc_pata.o
 
 # built-in only drivers from h8300/
 ide-core-$(CONFIG_H8300)		+= h8300/ide-h8300.o
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index 8a1c27f..40e5c66 100644
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -307,26 +307,24 @@
 	return on;
 }
 
-static int icside_dma_host_off(ide_drive_t *drive)
+static void icside_dma_host_off(ide_drive_t *drive)
 {
-	return 0;
 }
 
-static int icside_dma_off_quietly(ide_drive_t *drive)
+static void icside_dma_off_quietly(ide_drive_t *drive)
 {
 	drive->using_dma = 0;
-	return icside_dma_host_off(drive);
 }
 
-static int icside_dma_host_on(ide_drive_t *drive)
+static void icside_dma_host_on(ide_drive_t *drive)
 {
-	return 0;
 }
 
 static int icside_dma_on(ide_drive_t *drive)
 {
 	drive->using_dma = 1;
-	return icside_dma_host_on(drive);
+
+	return 0;
 }
 
 static int icside_dma_check(ide_drive_t *drive)
@@ -365,10 +363,7 @@
 out:
 	on = icside_set_speed(drive, xfer_mode);
 
-	if (on)
-		return icside_dma_on(drive);
-	else
-		return icside_dma_off_quietly(drive);
+	return on ? 0 : -1;
 }
 
 static int icside_dma_end(ide_drive_t *drive)
@@ -497,9 +492,9 @@
 	hwif->autodma		= autodma;
 
 	hwif->ide_dma_check	= icside_dma_check;
-	hwif->ide_dma_host_off	= icside_dma_host_off;
-	hwif->ide_dma_off_quietly = icside_dma_off_quietly;
-	hwif->ide_dma_host_on	= icside_dma_host_on;
+	hwif->dma_host_off	= icside_dma_host_off;
+	hwif->dma_off_quietly	= icside_dma_off_quietly;
+	hwif->dma_host_on	= icside_dma_host_on;
 	hwif->ide_dma_on	= icside_dma_on;
 	hwif->dma_setup		= icside_dma_setup;
 	hwif->dma_exec_cmd	= icside_dma_exec_cmd;
@@ -556,7 +551,7 @@
 		 * Ensure we're using MMIO
 		 */
 		default_hwif_mmiops(hwif);
-		hwif->mmio = 2;
+		hwif->mmio = 1;
 
 		for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
 			hwif->hw.io_ports[i] = port;
diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c
index 3058217..9c6c49f 100644
--- a/drivers/ide/arm/rapide.c
+++ b/drivers/ide/arm/rapide.c
@@ -46,7 +46,7 @@
 	hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
 	hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
 	hwif->hw.irq = hwif->irq = irq;
-	hwif->mmio = 2;
+	hwif->mmio = 1;
 	default_hwif_mmiops(hwif);
 
 	return hwif;
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
index 5797e0b..6b2d152 100644
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -682,9 +682,12 @@
 static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int);
 static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
 static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int);
-static int cris_dma_off (ide_drive_t *drive);
 static int cris_dma_on (ide_drive_t *drive);
 
+static void cris_dma_off(ide_drive_t *drive)
+{
+}
+
 static void tune_cris_ide(ide_drive_t *drive, u8 pio)
 {
 	int setup, strobe, hold;
@@ -795,7 +798,7 @@
 		                0, 0, cris_ide_ack_intr,
 		                ide_default_irq(0));
 		ide_register_hw(&hw, &hwif);
-		hwif->mmio = 2;
+		hwif->mmio = 1;
 		hwif->chipset = ide_etrax100;
 		hwif->tuneproc = &tune_cris_ide;
 		hwif->speedproc = &speed_cris_ide;
@@ -814,13 +817,16 @@
 		hwif->OUTBSYNC = &cris_ide_outbsync;
 		hwif->INB = &cris_ide_inb;
 		hwif->INW = &cris_ide_inw;
-		hwif->ide_dma_host_off = &cris_dma_off;
-		hwif->ide_dma_host_on = &cris_dma_on;
-		hwif->ide_dma_off_quietly = &cris_dma_off;
+		hwif->dma_host_off = &cris_dma_off;
+		hwif->dma_host_on = &cris_dma_on;
+		hwif->dma_off_quietly = &cris_dma_off;
 		hwif->udma_four = 0;
 		hwif->ultra_mask = cris_ultra_mask;
 		hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */
 		hwif->swdma_mask = 0x07; /* Singleword DMA 0-2 */
+		hwif->autodma = 1;
+		hwif->drives[0].autodma = 1;
+		hwif->drives[1].autodma = 1;
 	}
 
 	/* Reset pulse */
@@ -835,11 +841,6 @@
 	cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0);
 }
 
-static int cris_dma_off (ide_drive_t *drive)
-{
-	return 0;
-}
-
 static int cris_dma_on (ide_drive_t *drive)
 {
 	return 0;
@@ -1045,17 +1046,10 @@
 
 static int cris_dma_check(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
-	struct hd_driveid* id = drive->id;
+	if (ide_use_dma(drive) && cris_config_drive_for_dma(drive))
+		return 0;
 
-	if (id && (id->capability & 1)) {
-		if (ide_use_dma(drive)) {
-			if (cris_config_drive_for_dma(drive))
-				return hwif->ide_dma_on(drive);
-		}
-	}
-
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 static int cris_dma_end(ide_drive_t *drive)
diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c
index 608ca87..88750a3 100644
--- a/drivers/ide/h8300/ide-h8300.c
+++ b/drivers/ide/h8300/ide-h8300.c
@@ -76,13 +76,11 @@
 {
 	default_hwif_iops(hwif);
 
-	hwif->mmio  = 2;
+	hwif->mmio  = 1;
 	hwif->OUTW  = mm_outw;
 	hwif->OUTSW = mm_outsw;
 	hwif->INW   = mm_inw;
 	hwif->INSW  = mm_insw;
-	hwif->OUTL  = NULL;
-	hwif->INL   = NULL;
 	hwif->OUTSL = NULL;
 	hwif->INSL  = NULL;
 }
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 5969cec..45a928c 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -687,15 +687,8 @@
 static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
 {
 	struct request *rq = HWGROUP(drive)->rq;
-	ide_hwif_t *hwif = HWIF(drive);
 	int stat, err, sense_key;
 	
-	/* We may have bogus DMA interrupts in PIO state here */
-	if (HWIF(drive)->dma_status && hwif->atapi_irq_bogon) {
-		stat = hwif->INB(hwif->dma_status);
-		/* Should we force the bit as well ? */
-		hwif->OUTB(stat, hwif->dma_status);
-	}
 	/* Check for errors. */
 	stat = HWIF(drive)->INB(IDE_STATUS_REG);
 	if (stat_ret)
@@ -930,6 +923,10 @@
 		HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);
  
 	if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
+		/* waiting for CDB interrupt, not DMA yet. */
+		if (info->dma)
+			drive->waiting_for_dma = 0;
+
 		/* packet command */
 		ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry);
 		return ide_started;
@@ -972,6 +969,10 @@
 		/* Check for errors. */
 		if (cdrom_decode_status(drive, DRQ_STAT, NULL))
 			return ide_stopped;
+
+		/* Ok, next interrupt will be DMA interrupt. */
+		if (info->dma)
+			drive->waiting_for_dma = 1;
 	} else {
 		/* Otherwise, we must wait for DRQ to get set. */
 		if (ide_wait_stat(&startstop, drive, DRQ_STAT,
@@ -1103,7 +1104,7 @@
 	if (dma) {
 		info->dma = 0;
 		if ((dma_error = HWIF(drive)->ide_dma_end(drive)))
-			__ide_dma_off(drive);
+			ide_dma_off(drive);
 	}
 
 	if (cdrom_decode_status(drive, 0, &stat))
@@ -1699,7 +1700,7 @@
 	if (dma) {
 		if (dma_error) {
 			printk(KERN_ERR "ide-cd: dma error\n");
-			__ide_dma_off(drive);
+			ide_dma_off(drive);
 			return ide_error(drive, "dma error", stat);
 		}
 
@@ -1825,7 +1826,7 @@
 		info->dma = 0;
 		if ((dma_error = HWIF(drive)->ide_dma_end(drive))) {
 			printk(KERN_ERR "ide-cd: write dma error\n");
-			__ide_dma_off(drive);
+			ide_dma_off(drive);
 		}
 	}
 
@@ -3254,14 +3255,6 @@
 	if (drive->autotune == IDE_TUNE_DEFAULT ||
 	    drive->autotune == IDE_TUNE_AUTO)
 		drive->dsc_overlap = (drive->next != drive);
-#if 0
-	drive->dsc_overlap = (HWIF(drive)->no_dsc) ? 0 : 1;
-	if (HWIF(drive)->no_dsc) {
-		printk(KERN_INFO "ide-cd: %s: disabling DSC overlap\n",
-			drive->name);
-		drive->dsc_overlap = 0;
-	}
-#endif
 
 	if (ide_cdrom_register(drive, nslots)) {
 		printk (KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
@@ -3360,21 +3353,16 @@
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
 	struct cdrom_info *info;
-	ide_drive_t *drive;
 	int rc = -ENOMEM;
 
 	if (!(info = ide_cd_get(disk)))
 		return -ENXIO;
 
-	drive = info->drive;
-
-	drive->usage++;
-
 	if (!info->buffer)
-		info->buffer = kmalloc(SECTOR_BUFFER_SIZE,
-					GFP_KERNEL|__GFP_REPEAT);
-        if (!info->buffer || (rc = cdrom_open(&info->devinfo, inode, file)))
-		drive->usage--;
+		info->buffer = kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL|__GFP_REPEAT);
+
+	if (info->buffer)
+		rc = cdrom_open(&info->devinfo, inode, file);
 
 	if (rc < 0)
 		ide_cd_put(info);
@@ -3386,10 +3374,8 @@
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
 	struct cdrom_info *info = ide_cd_g(disk);
-	ide_drive_t *drive = info->drive;
 
 	cdrom_release (&info->devinfo, file);
-	drive->usage--;
 
 	ide_cd_put(info);
 
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 0a05a37..e2cea18 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -77,6 +77,7 @@
 	ide_driver_t	*driver;
 	struct gendisk	*disk;
 	struct kref	kref;
+	unsigned int	openers;	/* protected by BKL for now */
 };
 
 static DEFINE_MUTEX(idedisk_ref_mutex);
@@ -1081,8 +1082,9 @@
 
 	drive = idkp->drive;
 
-	drive->usage++;
-	if (drive->removable && drive->usage == 1) {
+	idkp->openers++;
+
+	if (drive->removable && idkp->openers == 1) {
 		ide_task_t args;
 		memset(&args, 0, sizeof(ide_task_t));
 		args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORLOCK;
@@ -1106,9 +1108,10 @@
 	struct ide_disk_obj *idkp = ide_disk_g(disk);
 	ide_drive_t *drive = idkp->drive;
 
-	if (drive->usage == 1)
+	if (idkp->openers == 1)
 		ide_cacheflush_p(drive);
-	if (drive->removable && drive->usage == 1) {
+
+	if (drive->removable && idkp->openers == 1) {
 		ide_task_t args;
 		memset(&args, 0, sizeof(ide_task_t));
 		args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORUNLOCK;
@@ -1117,7 +1120,8 @@
 		if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL))
 			drive->doorlocking = 0;
 	}
-	drive->usage--;
+
+	idkp->openers--;
 
 	ide_disk_put(idkp);
 
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 56efed6..08e7cd0 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -348,15 +348,14 @@
 static int config_drive_for_dma (ide_drive_t *drive)
 {
 	struct hd_driveid *id = drive->id;
-	ide_hwif_t *hwif = HWIF(drive);
 
-	if ((id->capability & 1) && hwif->autodma) {
+	if ((id->capability & 1) && drive->hwif->autodma) {
 		/*
 		 * Enable DMA on any drive that has
 		 * UltraDMA (mode 0/1/2/3/4/5/6) enabled
 		 */
 		if ((id->field_valid & 4) && ((id->dma_ultra >> 8) & 0x7f))
-			return hwif->ide_dma_on(drive);
+			return 0;
 		/*
 		 * Enable DMA on any drive that has mode2 DMA
 		 * (multi or single) enabled
@@ -364,14 +363,14 @@
 		if (id->field_valid & 2)	/* regular DMA */
 			if ((id->dma_mword & 0x404) == 0x404 ||
 			    (id->dma_1word & 0x404) == 0x404)
-				return hwif->ide_dma_on(drive);
+				return 0;
 
 		/* Consult the list of known "good" drives */
 		if (__ide_dma_good_drive(drive))
-			return hwif->ide_dma_on(drive);
+			return 0;
 	}
-//	if (hwif->tuneproc != NULL) hwif->tuneproc(drive, 255);
-	return hwif->ide_dma_off_quietly(drive);
+
+	return -1;
 }
 
 /**
@@ -415,72 +414,68 @@
 }
 
 /**
- *	__ide_dma_host_off	-	Generic DMA kill
+ *	ide_dma_host_off	-	Generic DMA kill
  *	@drive: drive to control
  *
  *	Perform the generic IDE controller DMA off operation. This
  *	works for most IDE bus mastering controllers
  */
 
-int __ide_dma_host_off (ide_drive_t *drive)
+void ide_dma_host_off(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 unit			= (drive->select.b.unit & 0x01);
 	u8 dma_stat		= hwif->INB(hwif->dma_status);
 
 	hwif->OUTB((dma_stat & ~(1<<(5+unit))), hwif->dma_status);
-	return 0;
 }
 
-EXPORT_SYMBOL(__ide_dma_host_off);
+EXPORT_SYMBOL(ide_dma_host_off);
 
 /**
- *	__ide_dma_host_off_quietly	-	Generic DMA kill
+ *	ide_dma_off_quietly	-	Generic DMA kill
  *	@drive: drive to control
  *
  *	Turn off the current DMA on this IDE controller. 
  */
 
-int __ide_dma_off_quietly (ide_drive_t *drive)
+void ide_dma_off_quietly(ide_drive_t *drive)
 {
 	drive->using_dma = 0;
 	ide_toggle_bounce(drive, 0);
 
-	if (HWIF(drive)->ide_dma_host_off(drive))
-		return 1;
-
-	return 0;
+	drive->hwif->dma_host_off(drive);
 }
 
-EXPORT_SYMBOL(__ide_dma_off_quietly);
+EXPORT_SYMBOL(ide_dma_off_quietly);
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
 /**
- *	__ide_dma_off	-	disable DMA on a device
+ *	ide_dma_off	-	disable DMA on a device
  *	@drive: drive to disable DMA on
  *
  *	Disable IDE DMA for a device on this IDE controller.
  *	Inform the user that DMA has been disabled.
  */
 
-int __ide_dma_off (ide_drive_t *drive)
+void ide_dma_off(ide_drive_t *drive)
 {
 	printk(KERN_INFO "%s: DMA disabled\n", drive->name);
-	return HWIF(drive)->ide_dma_off_quietly(drive);
+	drive->hwif->dma_off_quietly(drive);
 }
 
-EXPORT_SYMBOL(__ide_dma_off);
+EXPORT_SYMBOL(ide_dma_off);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 /**
- *	__ide_dma_host_on	-	Enable DMA on a host
+ *	ide_dma_host_on	-	Enable DMA on a host
  *	@drive: drive to enable for DMA
  *
  *	Enable DMA on an IDE controller following generic bus mastering
  *	IDE controller behaviour
  */
- 
-int __ide_dma_host_on (ide_drive_t *drive)
+
+void ide_dma_host_on(ide_drive_t *drive)
 {
 	if (drive->using_dma) {
 		ide_hwif_t *hwif	= HWIF(drive);
@@ -488,12 +483,10 @@
 		u8 dma_stat		= hwif->INB(hwif->dma_status);
 
 		hwif->OUTB((dma_stat|(1<<(5+unit))), hwif->dma_status);
-		return 0;
 	}
-	return 1;
 }
 
-EXPORT_SYMBOL(__ide_dma_host_on);
+EXPORT_SYMBOL(ide_dma_host_on);
 
 /**
  *	__ide_dma_on		-	Enable DMA on a device
@@ -511,8 +504,7 @@
 	drive->using_dma = 1;
 	ide_toggle_bounce(drive, 1);
 
-	if (HWIF(drive)->ide_dma_host_on(drive))
-		return 1;
+	drive->hwif->dma_host_on(drive);
 
 	return 0;
 }
@@ -565,7 +557,10 @@
 	}
 
 	/* PRD table */
-	hwif->OUTL(hwif->dmatable_dma, hwif->dma_prdtable);
+	if (hwif->mmio)
+		writel(hwif->dmatable_dma, (void __iomem *)hwif->dma_prdtable);
+	else
+		outl(hwif->dmatable_dma, hwif->dma_prdtable);
 
 	/* specify r/w */
 	hwif->OUTB(reading, hwif->dma_command);
@@ -680,6 +675,9 @@
 	struct hd_driveid *id = drive->id;
 	ide_hwif_t *hwif = drive->hwif;
 
+	if ((id->capability & 1) == 0 || drive->autodma == 0)
+		return 0;
+
 	/* consult the list of known "bad" drives */
 	if (__ide_dma_bad_drive(drive))
 		return 0;
@@ -753,12 +751,37 @@
 	return;
 bug_dma_off:
 	printk(", BUG DMA OFF");
-	hwif->ide_dma_off_quietly(drive);
+	hwif->dma_off_quietly(drive);
 	return;
 }
 
 EXPORT_SYMBOL(ide_dma_verbose);
 
+int ide_set_dma(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	int rc;
+
+	rc = hwif->ide_dma_check(drive);
+
+	switch(rc) {
+	case -1: /* DMA needs to be disabled */
+		hwif->dma_off_quietly(drive);
+		return 0;
+	case  0: /* DMA needs to be enabled */
+		return hwif->ide_dma_on(drive);
+	case  1: /* DMA setting cannot be changed */
+		break;
+	default:
+		BUG();
+		break;
+	}
+
+	return rc;
+}
+
+EXPORT_SYMBOL_GPL(ide_set_dma);
+
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 int __ide_dma_lostirq (ide_drive_t *drive)
 {
@@ -809,7 +832,7 @@
 {
 	ide_release_dma_engine(hwif);
 
-	if (hwif->mmio == 2)
+	if (hwif->mmio)
 		return 1;
 	else
 		return ide_release_iomio_dma(hwif);
@@ -878,9 +901,9 @@
 
 static int ide_dma_iobase(ide_hwif_t *hwif, unsigned long base, unsigned int ports)
 {
-	if (hwif->mmio == 2)
+	if (hwif->mmio)
 		return ide_mapped_mmio_dma(hwif, base,ports);
-	BUG_ON(hwif->mmio == 1);
+
 	return ide_iomio_dma(hwif, base, ports);
 }
 
@@ -908,14 +931,14 @@
 	if (!(hwif->dma_prdtable))
 		hwif->dma_prdtable	= (hwif->dma_base + 4);
 
-	if (!hwif->ide_dma_off_quietly)
-		hwif->ide_dma_off_quietly = &__ide_dma_off_quietly;
-	if (!hwif->ide_dma_host_off)
-		hwif->ide_dma_host_off = &__ide_dma_host_off;
+	if (!hwif->dma_off_quietly)
+		hwif->dma_off_quietly = &ide_dma_off_quietly;
+	if (!hwif->dma_host_off)
+		hwif->dma_host_off = &ide_dma_host_off;
 	if (!hwif->ide_dma_on)
 		hwif->ide_dma_on = &__ide_dma_on;
-	if (!hwif->ide_dma_host_on)
-		hwif->ide_dma_host_on = &__ide_dma_host_on;
+	if (!hwif->dma_host_on)
+		hwif->dma_host_on = &ide_dma_host_on;
 	if (!hwif->ide_dma_check)
 		hwif->ide_dma_check = &__ide_dma_check;
 	if (!hwif->dma_setup)
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index d33717c..57cd21c 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -279,6 +279,7 @@
 	ide_driver_t	*driver;
 	struct gendisk	*disk;
 	struct kref	kref;
+	unsigned int	openers;	/* protected by BKL for now */
 
 	/* Current packet command */
 	idefloppy_pc_t *pc;
@@ -866,7 +867,7 @@
 	if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
 		printk(KERN_ERR "ide-floppy: The floppy wants to issue "
 			"more interrupts in DMA mode\n");
-		(void)__ide_dma_off(drive);
+		ide_dma_off(drive);
 		return ide_do_reset(drive);
 	}
 
@@ -1096,9 +1097,9 @@
 	pc->current_position = pc->buffer;
 	bcount.all = min(pc->request_transfer, 63 * 1024);
 
-	if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) {
-		(void)__ide_dma_off(drive);
-	}
+	if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags))
+		ide_dma_off(drive);
+
 	feature.all = 0;
 
 	if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
@@ -1433,7 +1434,8 @@
 	
 	drive->bios_cyl = 0;
 	drive->bios_head = drive->bios_sect = 0;
-	floppy->blocks = floppy->bs_factor = 0;
+	floppy->blocks = 0;
+	floppy->bs_factor = 1;
 	set_capacity(floppy->disk, 0);
 
 	idefloppy_create_read_capacity_cmd(&pc);
@@ -1949,9 +1951,9 @@
 
 	drive = floppy->drive;
 
-	drive->usage++;
+	floppy->openers++;
 
-	if (drive->usage == 1) {
+	if (floppy->openers == 1) {
 		clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
 		/* Just in case */
 
@@ -1969,13 +1971,11 @@
 		    ** capacity of the drive or begin the format - Sam
 		    */
 		    ) {
-			drive->usage--;
 			ret = -EIO;
 			goto out_put_floppy;
 		}
 
 		if (floppy->wp && (filp->f_mode & 2)) {
-			drive->usage--;
 			ret = -EROFS;
 			goto out_put_floppy;
 		}
@@ -1987,13 +1987,13 @@
 		}
 		check_disk_change(inode->i_bdev);
 	} else if (test_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags)) {
-		drive->usage--;
 		ret = -EBUSY;
 		goto out_put_floppy;
 	}
 	return 0;
 
 out_put_floppy:
+	floppy->openers--;
 	ide_floppy_put(floppy);
 	return ret;
 }
@@ -2007,7 +2007,7 @@
 	
 	debug_log(KERN_INFO "Reached idefloppy_release\n");
 
-	if (drive->usage == 1) {
+	if (floppy->openers == 1) {
 		/* IOMEGA Clik! drives do not support lock/unlock commands */
                 if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
 			idefloppy_create_prevent_cmd(&pc, 0);
@@ -2016,7 +2016,8 @@
 
 		clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
 	}
-	drive->usage--;
+
+	floppy->openers--;
 
 	ide_floppy_put(floppy);
 
@@ -2050,7 +2051,7 @@
 		prevent = 0;
 		/* fall through */
 	case CDROM_LOCKDOOR:
-		if (drive->usage > 1)
+		if (floppy->openers > 1)
 			return -EBUSY;
 
 		/* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */
@@ -2072,7 +2073,7 @@
 		if (!(file->f_mode & 2))
 			return -EPERM;
 
-		if (drive->usage > 1) {
+		if (floppy->openers > 1) {
 			/* Don't format if someone is using the disk */
 
 			clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS,
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 2614f41..c193553 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -226,7 +226,7 @@
 			break;
 		if (drive->hwif->ide_dma_check == NULL)
 			break;
-		drive->hwif->ide_dma_check(drive);
+		ide_set_dma(drive);
 		break;
 	}
 	pm->pm_step = ide_pm_state_completed;
@@ -1351,7 +1351,7 @@
 	 */
 	drive->retry_pio++;
 	drive->state = DMA_PIO_RETRY;
-	(void) hwif->ide_dma_off_quietly(drive);
+	hwif->dma_off_quietly(drive);
 
 	/*
 	 * un-busy drive etc (hwgroup->busy is cleared on return) and
@@ -1646,6 +1646,17 @@
 	del_timer(&hwgroup->timer);
 	spin_unlock(&ide_lock);
 
+	/* Some controllers might set DMA INTR no matter DMA or PIO;
+	 * bmdma status might need to be cleared even for
+	 * PIO interrupts to prevent spurious/lost irq.
+	 */
+	if (hwif->ide_dma_clear_irq && !(drive->waiting_for_dma))
+		/* ide_dma_end() needs bmdma status for error checking.
+		 * So, skip clearing bmdma status here and leave it
+		 * to ide_dma_end() if this is dma interrupt.
+		 */
+		hwif->ide_dma_clear_irq(drive);
+
 	if (drive->unmask)
 		local_irq_enable_in_hardirq();
 	/* service this interrupt, may set handler for next interrupt */
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index badde63..c67b3b1 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -49,11 +49,6 @@
 	insw(port, addr, count);
 }
 
-static u32 ide_inl (unsigned long port)
-{
-	return (u32) inl(port);
-}
-
 static void ide_insl (unsigned long port, void *addr, u32 count)
 {
 	insl(port, addr, count);
@@ -79,11 +74,6 @@
 	outsw(port, addr, count);
 }
 
-static void ide_outl (u32 val, unsigned long port)
-{
-	outl(val, port);
-}
-
 static void ide_outsl (unsigned long port, void *addr, u32 count)
 {
 	outsl(port, addr, count);
@@ -94,12 +84,10 @@
 	hwif->OUTB	= ide_outb;
 	hwif->OUTBSYNC	= ide_outbsync;
 	hwif->OUTW	= ide_outw;
-	hwif->OUTL	= ide_outl;
 	hwif->OUTSW	= ide_outsw;
 	hwif->OUTSL	= ide_outsl;
 	hwif->INB	= ide_inb;
 	hwif->INW	= ide_inw;
-	hwif->INL	= ide_inl;
 	hwif->INSW	= ide_insw;
 	hwif->INSL	= ide_insl;
 }
@@ -123,11 +111,6 @@
 	__ide_mm_insw((void __iomem *) port, addr, count);
 }
 
-static u32 ide_mm_inl (unsigned long port)
-{
-	return (u32) readl((void __iomem *) port);
-}
-
 static void ide_mm_insl (unsigned long port, void *addr, u32 count)
 {
 	__ide_mm_insl((void __iomem *) port, addr, count);
@@ -153,11 +136,6 @@
 	__ide_mm_outsw((void __iomem *) port, addr, count);
 }
 
-static void ide_mm_outl (u32 value, unsigned long port)
-{
-	writel(value, (void __iomem *) port);
-}
-
 static void ide_mm_outsl (unsigned long port, void *addr, u32 count)
 {
 	__ide_mm_outsl((void __iomem *) port, addr, count);
@@ -170,12 +148,10 @@
 	   this one is controller specific! */
 	hwif->OUTBSYNC	= ide_mm_outbsync;
 	hwif->OUTW	= ide_mm_outw;
-	hwif->OUTL	= ide_mm_outl;
 	hwif->OUTSW	= ide_mm_outsw;
 	hwif->OUTSL	= ide_mm_outsl;
 	hwif->INB	= ide_mm_inb;
 	hwif->INW	= ide_mm_inw;
-	hwif->INL	= ide_mm_inl;
 	hwif->INSW	= ide_mm_insw;
 	hwif->INSL	= ide_mm_insl;
 }
@@ -777,7 +753,7 @@
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->ide_dma_check)	 /* check if host supports DMA */
-		hwif->ide_dma_host_off(drive);
+		hwif->dma_host_off(drive);
 #endif
 
 	/*
@@ -854,9 +830,9 @@
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (speed >= XFER_SW_DMA_0)
-		hwif->ide_dma_host_on(drive);
+		hwif->dma_host_on(drive);
 	else if (hwif->ide_dma_check)	/* check if host supports DMA */
-		hwif->ide_dma_off_quietly(drive);
+		hwif->dma_off_quietly(drive);
 #endif
 
 	switch(speed) {
@@ -1066,12 +1042,12 @@
 {
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (drive->crc_count) {
-		(void) HWIF(drive)->ide_dma_off_quietly(drive);
+		drive->hwif->dma_off_quietly(drive);
 		ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive));
 		if (drive->current_speed >= XFER_SW_DMA_0)
 			(void) HWIF(drive)->ide_dma_on(drive);
 	} else
-		(void)__ide_dma_off(drive);
+		ide_dma_off(drive);
 #endif
 }
 
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 8237d89..8afce4c 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -205,6 +205,21 @@
 
 EXPORT_SYMBOL(ide_dma_enable);
 
+int ide_use_fast_pio(ide_drive_t *drive)
+{
+	struct hd_driveid *id = drive->id;
+
+	if ((id->capability & 1) && drive->autodma)
+		return 1;
+
+	if ((id->capability & 8) || (id->field_valid & 2))
+		return 1;
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(ide_use_fast_pio);
+
 /*
  * Standard (generic) timings for PIO modes, from ATA2 specification.
  * These timings are for access to the IDE data port register *only*.
@@ -349,7 +364,6 @@
 	int use_iordy = 0;
 	struct hd_driveid* id = drive->id;
 	int overridden  = 0;
-	int blacklisted = 0;
 
 	if (mode_wanted != 255) {
 		pio_mode = mode_wanted;
@@ -357,7 +371,6 @@
 		pio_mode = 0;
 	} else if ((pio_mode = ide_scan_pio_blacklist(id->model)) != -1) {
 		overridden = 1;
-		blacklisted = 1;
 		use_iordy = (pio_mode > 2);
 	} else {
 		pio_mode = id->tPIO;
@@ -409,7 +422,6 @@
 		d->cycle_time = cycle_time ? cycle_time : ide_pio_timings[pio_mode].cycle_time;
 		d->use_iordy = use_iordy;
 		d->overridden = overridden;
-		d->blacklisted = blacklisted;
 	}
 	return pio_mode;
 }
@@ -462,8 +474,6 @@
 		return -1;
 }
 
-EXPORT_SYMBOL_GPL(ide_set_xfer_rate);
-
 static void ide_dump_opcode(ide_drive_t *drive)
 {
 	struct request *rq;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 176bbc8..8afbd6c 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -853,11 +853,11 @@
 				 * things, if not checked and cleared.
 				 *   PARANOIA!!!
 				 */
-				hwif->ide_dma_off_quietly(drive);
+				hwif->dma_off_quietly(drive);
 #ifdef CONFIG_IDEDMA_ONLYDISK
 				if (drive->media == ide_disk)
 #endif
-					hwif->ide_dma_check(drive);
+					ide_set_dma(drive);
 			}
 		}
 	}
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index c6eec04..4e59239 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1970,7 +1970,7 @@
 		printk(KERN_ERR "ide-tape: The tape wants to issue more "
 				"interrupts in DMA mode\n");
 		printk(KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n");
-		(void)__ide_dma_off(drive);
+		ide_dma_off(drive);
 		return ide_do_reset(drive);
 	}
 	/* Get the number of bytes to transfer on this interrupt. */
@@ -2176,7 +2176,7 @@
 	if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) {
 		printk(KERN_WARNING "ide-tape: DMA disabled, "
 				"reverting to PIO\n");
-		(void)__ide_dma_off(drive);
+		ide_dma_off(drive);
 	}
 	if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
 		dma_ok = !hwif->dma_setup(drive);
@@ -4792,15 +4792,10 @@
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
 	struct ide_tape_obj *tape;
-	ide_drive_t *drive;
 
 	if (!(tape = ide_tape_get(disk)))
 		return -ENXIO;
 
-	drive = tape->drive;
-
-	drive->usage++;
-
 	return 0;
 }
 
@@ -4808,9 +4803,6 @@
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
 	struct ide_tape_obj *tape = ide_tape_g(disk);
-	ide_drive_t *drive = tape->drive;
-
-	drive->usage--;
 
 	ide_tape_put(tape);
 
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index c750f6c..b3c0818 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -389,9 +389,8 @@
 	unsigned long addr;
 	unsigned int i;
 
-	if (hwif->mmio == 2)
+	if (hwif->mmio)
 		return 0;
-	BUG_ON(hwif->mmio == 1);
 	addr = hwif->io_ports[IDE_CONTROL_OFFSET];
 	if (addr && !hwif_request_region(hwif, addr, 1))
 		goto control_region_busy;
@@ -438,7 +437,7 @@
 {
 	u32 i = 0;
 
-	if (hwif->mmio == 2)
+	if (hwif->mmio)
 		return;
 	if (hwif->io_ports[IDE_CONTROL_OFFSET])
 		release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
@@ -507,23 +506,22 @@
 	hwif->ide_dma_end		= tmp_hwif->ide_dma_end;
 	hwif->ide_dma_check		= tmp_hwif->ide_dma_check;
 	hwif->ide_dma_on		= tmp_hwif->ide_dma_on;
-	hwif->ide_dma_off_quietly	= tmp_hwif->ide_dma_off_quietly;
+	hwif->dma_off_quietly		= tmp_hwif->dma_off_quietly;
 	hwif->ide_dma_test_irq		= tmp_hwif->ide_dma_test_irq;
-	hwif->ide_dma_host_on		= tmp_hwif->ide_dma_host_on;
-	hwif->ide_dma_host_off		= tmp_hwif->ide_dma_host_off;
+	hwif->ide_dma_clear_irq		= tmp_hwif->ide_dma_clear_irq;
+	hwif->dma_host_on		= tmp_hwif->dma_host_on;
+	hwif->dma_host_off		= tmp_hwif->dma_host_off;
 	hwif->ide_dma_lostirq		= tmp_hwif->ide_dma_lostirq;
 	hwif->ide_dma_timeout		= tmp_hwif->ide_dma_timeout;
 
 	hwif->OUTB			= tmp_hwif->OUTB;
 	hwif->OUTBSYNC			= tmp_hwif->OUTBSYNC;
 	hwif->OUTW			= tmp_hwif->OUTW;
-	hwif->OUTL			= tmp_hwif->OUTL;
 	hwif->OUTSW			= tmp_hwif->OUTSW;
 	hwif->OUTSL			= tmp_hwif->OUTSL;
 
 	hwif->INB			= tmp_hwif->INB;
 	hwif->INW			= tmp_hwif->INW;
-	hwif->INL			= tmp_hwif->INL;
 	hwif->INSW			= tmp_hwif->INSW;
 	hwif->INSL			= tmp_hwif->INSL;
 
@@ -551,7 +549,6 @@
 	hwif->extra_ports		= tmp_hwif->extra_ports;
 	hwif->autodma			= tmp_hwif->autodma;
 	hwif->udma_four			= tmp_hwif->udma_four;
-	hwif->no_dsc			= tmp_hwif->no_dsc;
 
 	hwif->hwif_data			= tmp_hwif->hwif_data;
 }
@@ -1138,12 +1135,11 @@
 	if (HWIF(drive)->ide_dma_check == NULL)
 		return -EPERM;
 	if (arg) {
-		if (HWIF(drive)->ide_dma_check(drive)) return -EIO;
-		if (HWIF(drive)->ide_dma_on(drive)) return -EIO;
-	} else {
-		if (__ide_dma_off(drive))
+		if (ide_set_dma(drive))
 			return -EIO;
-	}
+		if (HWIF(drive)->ide_dma_on(drive)) return -EIO;
+	} else
+		ide_dma_off(drive);
 	return 0;
 #else
 	return -EPERM;
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c
index 0391a31..1ed224a 100644
--- a/drivers/ide/legacy/buddha.c
+++ b/drivers/ide/legacy/buddha.c
@@ -215,7 +215,7 @@
 			
 			index = ide_register_hw(&hw, &hwif);
 			if (index != -1) {
-				hwif->mmio = 2;
+				hwif->mmio = 1;
 				printk("ide%d: ", index);
 				switch(type) {
 				case BOARD_BUDDHA:
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c
index 64d4261..dcfadbb 100644
--- a/drivers/ide/legacy/gayle.c
+++ b/drivers/ide/legacy/gayle.c
@@ -167,7 +167,7 @@
 
 	index = ide_register_hw(&hw, &hwif);
 	if (index != -1) {
-	    hwif->mmio = 2;
+	    hwif->mmio = 1;
 	    switch (i) {
 		case 0:
 		    printk("ide%d: Gayle IDE interface (A%d style)\n", index,
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
index c48e87e..19ccd00 100644
--- a/drivers/ide/legacy/ht6560b.c
+++ b/drivers/ide/legacy/ht6560b.c
@@ -143,16 +143,16 @@
 		current_timing = timing;
 		if (drive->media != ide_disk || !drive->present)
 			select |= HT_PREFETCH_MODE;
-		(void) HWIF(drive)->INB(HT_CONFIG_PORT);
-		(void) HWIF(drive)->INB(HT_CONFIG_PORT);
-		(void) HWIF(drive)->INB(HT_CONFIG_PORT);
-		(void) HWIF(drive)->INB(HT_CONFIG_PORT);
-		HWIF(drive)->OUTB(select, HT_CONFIG_PORT);
+		(void)inb(HT_CONFIG_PORT);
+		(void)inb(HT_CONFIG_PORT);
+		(void)inb(HT_CONFIG_PORT);
+		(void)inb(HT_CONFIG_PORT);
+		outb(select, HT_CONFIG_PORT);
 		/*
 		 * Set timing for this drive:
 		 */
-		HWIF(drive)->OUTB(timing, IDE_SELECT_REG);
-		(void) HWIF(drive)->INB(IDE_STATUS_REG);
+		outb(timing, IDE_SELECT_REG);
+		(void)inb(IDE_STATUS_REG);
 #ifdef DEBUG
 		printk("ht6560b: %s: select=%#x timing=%#x\n",
 			drive->name, select, timing);
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
index b1730d7..4c0079a 100644
--- a/drivers/ide/legacy/macide.c
+++ b/drivers/ide/legacy/macide.c
@@ -141,7 +141,7 @@
 	}
 
         if (index != -1) {
-		hwif->mmio = 2;
+		hwif->mmio = 1;
 		if (macintosh_config->ide_type == MAC_IDE_QUADRA)
 			printk(KERN_INFO "ide%d: Macintosh Quadra IDE interface\n", index);
 		else if (macintosh_config->ide_type == MAC_IDE_PB)
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c
index 434a94f..74f0812 100644
--- a/drivers/ide/legacy/q40ide.c
+++ b/drivers/ide/legacy/q40ide.c
@@ -145,7 +145,7 @@
 	index = ide_register_hw(&hw, &hwif);
 	// **FIXME**
 	if (index != -1)
-		hwif->mmio = 2;
+		hwif->mmio = 1;
     }
 }
 
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index c7854ea..0a59d5e 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -181,12 +181,6 @@
 {
 	int mem_sttime;
 	int mem_stcfg;
-	unsigned long mode;
-
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-	if (ide_use_dma(drive))
-		mode = ide_dma_speed(drive, 0);
-#endif
 
 	mem_sttime = 0;
 	mem_stcfg  = au_readl(MEM_STCFG2);
@@ -195,7 +189,7 @@
 		auide_tune_drive(drive, speed - XFER_PIO_0);
 		return 0;
 	}
-	      
+
 	switch(speed) {
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
 	case XFER_MW_DMA_2:
@@ -207,7 +201,6 @@
 		mem_stcfg &= ~TOECS_MASK;
 		mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
 
-		mode = XFER_MW_DMA_2;
 		break;
 	case XFER_MW_DMA_1:
 		mem_sttime = SBC_IDE_TIMING(MDMA1);
@@ -218,7 +211,6 @@
 		mem_stcfg &= ~TOECS_MASK;
 		mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
 
-		mode = XFER_MW_DMA_1;
 		break;
 	case XFER_MW_DMA_0:
 		mem_sttime = SBC_IDE_TIMING(MDMA0);
@@ -229,14 +221,13 @@
 		mem_stcfg &= ~TOECS_MASK;
 		mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
 
-		mode = XFER_MW_DMA_0;
 		break;
 #endif
 	default:
 		return 1;
 	}
-	
-	if (ide_config_drive_speed(drive, mode))
+
+	if (ide_config_drive_speed(drive, speed))
 		return 1;
 
 	au_writel(mem_sttime,MEM_STTIME2);
@@ -423,9 +414,9 @@
 	speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA);
 	
 	if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
-		return HWIF(drive)->ide_dma_on(drive);
+		return 0;
 
-	return HWIF(drive)->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 static int auide_dma_test_irq(ide_drive_t *drive)
@@ -447,27 +438,24 @@
 	return 0;
 }
 
-static int auide_dma_host_on(ide_drive_t *drive)
+static void auide_dma_host_on(ide_drive_t *drive)
 {
-	return 0;
 }
 
 static int auide_dma_on(ide_drive_t *drive)
 {
 	drive->using_dma = 1;
-	return auide_dma_host_on(drive);
-}
 
-
-static int auide_dma_host_off(ide_drive_t *drive)
-{
 	return 0;
 }
 
-static int auide_dma_off_quietly(ide_drive_t *drive)
+static void auide_dma_host_off(ide_drive_t *drive)
+{
+}
+
+static void auide_dma_off_quietly(ide_drive_t *drive)
 {
 	drive->using_dma = 0;
-	return auide_dma_host_off(drive);
 }
 
 static int auide_dma_lostirq(ide_drive_t *drive)
@@ -717,7 +705,8 @@
 
 	/* hold should be on in all cases */
 	hwif->hold                      = 1;
-	hwif->mmio                      = 2;
+
+	hwif->mmio  = 1;
 
 	/* If the user has selected DDMA assisted copies,
 	   then set up a few local I/O function entry points 
@@ -732,7 +721,7 @@
 	hwif->speedproc                 = &auide_tune_chipset;
 
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-	hwif->ide_dma_off_quietly       = &auide_dma_off_quietly;
+	hwif->dma_off_quietly		= &auide_dma_off_quietly;
 	hwif->ide_dma_timeout           = &auide_dma_timeout;
 
 	hwif->ide_dma_check             = &auide_dma_check;
@@ -741,8 +730,8 @@
 	hwif->ide_dma_end               = &auide_dma_end;
 	hwif->dma_setup                 = &auide_dma_setup;
 	hwif->ide_dma_test_irq          = &auide_dma_test_irq;
-	hwif->ide_dma_host_off          = &auide_dma_host_off;
-	hwif->ide_dma_host_on           = &auide_dma_host_on;
+	hwif->dma_host_off		= &auide_dma_host_off;
+	hwif->dma_host_on		= &auide_dma_host_on;
 	hwif->ide_dma_lostirq           = &auide_dma_lostirq;
 	hwif->ide_dma_on                = &auide_dma_on;
 
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
index 09c9e79..81fa068 100644
--- a/drivers/ide/mips/swarm.c
+++ b/drivers/ide/mips/swarm.c
@@ -115,7 +115,7 @@
 	/* Setup MMIO ops.  */
 	default_hwif_mmiops(hwif);
 	/* Prevent resource map manipulation.  */
-	hwif->mmio = 2;
+	hwif->mmio = 1;
 	hwif->noprobe = 0;
 
 	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index d261bfb..990eafe 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -94,9 +94,9 @@
 	switch(hwif->pci_dev->device) {
 		case PCI_DEVICE_ID_ARTOP_ATP865:
 		case PCI_DEVICE_ID_ARTOP_ATP865R:
-			mode = (hwif->INB(((hwif->channel) ?
-					hwif->mate->dma_status :
-					hwif->dma_status)) & 0x10) ? 4 : 3;
+			mode = (inb(hwif->channel ?
+				    hwif->mate->dma_status :
+				    hwif->dma_status) & 0x10) ? 4 : 3;
 			break;
 		case PCI_DEVICE_ID_ARTOP_ATP860:
 		case PCI_DEVICE_ID_ARTOP_ATP860R:
@@ -209,25 +209,13 @@
 
 static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-	if ((id->capability & 1) && drive->autodma) {
-
-		if (ide_use_dma(drive)) {
-			if (config_chipset_for_dma(drive))
-				return hwif->ide_dma_on(drive);
-		}
-
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
+	if (ide_use_fast_pio(drive))
 		aec62xx_tune_drive(drive, 5);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return -1;
 }
 
 static int aec62xx_irq_timeout (ide_drive_t *drive)
@@ -286,10 +274,8 @@
 	hwif->tuneproc = &aec62xx_tune_drive;
 	hwif->speedproc = &aec62xx_tune_chipset;
 
-	if (hwif->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
+	if (hwif->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
 		hwif->serialized = hwif->channel;
-		hwif->no_dsc = 1;
-	}
 
 	if (hwif->mate)
 		hwif->mate->serialized = hwif->serialized;
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index 68df77e..4debd18 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -507,17 +507,15 @@
  *
  *	Configure a drive for DMA operation. If DMA is not possible we
  *	drop the drive into PIO mode instead.
- *
- *	FIXME: exactly what are we trying to return here
  */
- 
+
 static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct hd_driveid *id	= drive->id;
 
 	if ((m5229_revision<=0x20) && (drive->media!=ide_disk))
-		return hwif->ide_dma_off_quietly(drive);
+		goto no_dma_set;
 
 	drive->init_speed = 0;
 
@@ -552,9 +550,10 @@
 ata_pio:
 		hwif->tuneproc(drive, 255);
 no_dma_set:
-		return hwif->ide_dma_off_quietly(drive);
+		return -1;
 	}
-	return hwif->ide_dma_on(drive);
+
+	return 0;
 }
 
 /**
@@ -852,8 +851,8 @@
 {
 	if (m5229_revision < 0x20)
 		return;
-	if (!(hwif->channel))
-		hwif->OUTB(hwif->INB(dmabase+2) & 0x60, dmabase+2);
+	if (!hwif->channel)
+		outb(inb(dmabase + 2) & 0x60, dmabase + 2);
 	ide_setup_dma(hwif, dmabase, 8);
 }
 
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index a433699..7989bdd 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -304,8 +304,9 @@
 	amd_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);
+		return 0;
+
+	return -1;
 }
 
 /*
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index 982ac31..2d48af3 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -101,7 +101,7 @@
 	}
 }
 
-static int atiixp_ide_dma_host_on(ide_drive_t *drive)
+static void atiixp_dma_host_on(ide_drive_t *drive)
 {
 	struct pci_dev *dev = drive->hwif->pci_dev;
 	unsigned long flags;
@@ -118,10 +118,10 @@
 
 	spin_unlock_irqrestore(&atiixp_lock, flags);
 
-	return __ide_dma_host_on(drive);
+	ide_dma_host_on(drive);
 }
 
-static int atiixp_ide_dma_host_off(ide_drive_t *drive)
+static void atiixp_dma_host_off(ide_drive_t *drive)
 {
 	struct pci_dev *dev = drive->hwif->pci_dev;
 	unsigned long flags;
@@ -135,7 +135,7 @@
 
 	spin_unlock_irqrestore(&atiixp_lock, flags);
 
-	return __ide_dma_host_off(drive);
+	ide_dma_host_off(drive);
 }
 
 /**
@@ -235,11 +235,8 @@
 {
 	u8 speed = ide_dma_speed(drive, atiixp_ratemask(drive));
 
-	/* If no DMA speed was available then disable DMA and use PIO. */
-	if (!speed) {
-		u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
-		speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;
-	}
+	if (!speed)
+		return 0;
 
 	(void) atiixp_speedproc(drive, speed);
 	return ide_dma_enable(drive);
@@ -255,30 +252,20 @@
 
 static int atiixp_dma_check(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
 	u8 tspeed, speed;
 
 	drive->init_speed = 0;
 
-	if ((id->capability & 1) && drive->autodma) {
+	if (ide_use_dma(drive) && atiixp_config_drive_for_dma(drive))
+		return 0;
 
-		if (ide_use_dma(drive)) {
-			if (atiixp_config_drive_for_dma(drive))
-				return hwif->ide_dma_on(drive);
-		}
-
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
+	if (ide_use_fast_pio(drive)) {
 		tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
 		speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;
-		hwif->speedproc(drive, speed);
-		return hwif->ide_dma_off_quietly(drive);
+		atiixp_speedproc(drive, speed);
 	}
-	/* IORDY not supported */
-	return 0;
+
+	return -1;
 }
 
 /**
@@ -318,8 +305,8 @@
 	else
 		hwif->udma_four = 0;
 
-	hwif->ide_dma_host_on = &atiixp_ide_dma_host_on;
-	hwif->ide_dma_host_off = &atiixp_ide_dma_host_off;
+	hwif->dma_host_on = &atiixp_dma_host_on;
+	hwif->dma_host_off = &atiixp_dma_host_off;
 	hwif->ide_dma_check = &atiixp_dma_check;
 	if (!noautodma)
 		hwif->autodma = 1;
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index aee947e..49df275 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -466,36 +466,21 @@
 	if (!speed)
 		return 0;
 
-	if(ide_set_xfer_rate(drive, speed))
-		return 0; 
-
-	if (!drive->init_speed)
-		drive->init_speed = speed;
+	if (cmd64x_tune_chipset(drive, speed))
+		return 0;
 
 	return ide_dma_enable(drive);
 }
 
 static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-	if ((id != NULL) && ((id->capability & 1) != 0) && drive->autodma) {
-
-		if (ide_use_dma(drive)) {
-			if (config_chipset_for_dma(drive))
-				return hwif->ide_dma_on(drive);
-		}
-
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
+	if (ide_use_fast_pio(drive))
 		config_chipset_for_pio(drive, 1);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return -1;
 }
 
 static int cmd64x_alt_dma_status (struct pci_dev *dev)
@@ -518,13 +503,13 @@
 
 	drive->waiting_for_dma = 0;
 	/* read DMA command state */
-	dma_cmd = hwif->INB(hwif->dma_command);
+	dma_cmd = inb(hwif->dma_command);
 	/* stop DMA */
-	hwif->OUTB((dma_cmd & ~1), hwif->dma_command);
+	outb(dma_cmd & ~1, hwif->dma_command);
 	/* get DMA status */
-	dma_stat = hwif->INB(hwif->dma_status);
+	dma_stat = inb(hwif->dma_status);
 	/* clear the INTR & ERROR bits */
-	hwif->OUTB(dma_stat|6, hwif->dma_status);
+	outb(dma_stat | 6, hwif->dma_status);
 	if (cmd64x_alt_dma_status(dev)) {
 		u8 dma_intr	= 0;
 		u8 dma_mask	= (hwif->channel) ? ARTTIM23_INTR_CH1 :
@@ -546,7 +531,7 @@
 	struct pci_dev *dev		= hwif->pci_dev;
         u8 dma_alt_stat = 0, mask	= (hwif->channel) ? MRDMODE_INTR_CH1 :
 							    MRDMODE_INTR_CH0;
-	u8 dma_stat = hwif->INB(hwif->dma_status);
+	u8 dma_stat = inb(hwif->dma_status);
 
 	(void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat);
 #ifdef DEBUG
@@ -576,13 +561,13 @@
 
 	drive->waiting_for_dma = 0;
 	/* get DMA status */
-	dma_stat = hwif->INB(hwif->dma_status);
+	dma_stat = inb(hwif->dma_status);
 	/* read DMA command state */
-	dma_cmd = hwif->INB(hwif->dma_command);
+	dma_cmd = inb(hwif->dma_command);
 	/* stop DMA */
-	hwif->OUTB((dma_cmd & ~1), hwif->dma_command);
+	outb(dma_cmd & ~1, hwif->dma_command);
 	/* clear the INTR & ERROR bits */
-	hwif->OUTB(dma_stat|6, hwif->dma_status);
+	outb(dma_stat | 6, hwif->dma_status);
 	/* and free any DMA resources */
 	ide_destroy_dmatable(drive);
 	/* verify good DMA status */
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index ba6786a..400859a 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -132,12 +132,11 @@
 
 static int cs5520_config_drive_xfer_rate(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = HWIF(drive);
-
 	/* Tune the drive for PIO modes up to PIO 4 */	
 	cs5520_tune_drive(drive, 4);
+
 	/* Then tell the core to use DMA operations */
-	return hwif->ide_dma_on(drive);
+	return 0;
 }
 
 /*
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index 9bf5fdf..b2d7c13 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -81,8 +81,8 @@
 
 	pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
 	if (!cs5530_set_xfer_mode(drive, modes[pio])) {
-		format = (hwif->INL(basereg+4) >> 31) & 1;
-		hwif->OUTL(cs5530_pio_timings[format][pio],
+		format = (inl(basereg + 4) >> 31) & 1;
+		outl(cs5530_pio_timings[format][pio],
 			basereg+(drive->select.b.unit<<3));
 	}
 }
@@ -103,16 +103,13 @@
 	int			unit = drive->select.b.unit;
 	ide_drive_t		*mate = &hwif->drives[unit^1];
 	struct hd_driveid	*id = drive->id;
-	unsigned int		reg, timings;
+	unsigned int		reg, timings = 0;
 	unsigned long		basereg;
 
 	/*
 	 * Default to DMA-off in case we run into trouble here.
 	 */
-	hwif->ide_dma_off_quietly(drive);
-	/* turn off DMA while we fiddle */
-	hwif->ide_dma_host_off(drive);
-	/* clear DMA_capable bit */
+	hwif->dma_off_quietly(drive);
 
 	/*
 	 * The CS5530 specifies that two drives sharing a cable cannot
@@ -182,30 +179,24 @@
 		case XFER_MW_DMA_1:	timings = 0x00012121; break;
 		case XFER_MW_DMA_2:	timings = 0x00002020; break;
 		default:
-			printk(KERN_ERR "%s: cs5530_config_dma: huh? mode=%02x\n",
-				drive->name, mode);
-			return 1;	/* failure */
+			BUG();
+			break;
 	}
 	basereg = CS5530_BASEREG(hwif);
-	reg = hwif->INL(basereg+4);		/* get drive0 config register */
+	reg = inl(basereg + 4);			/* get drive0 config register */
 	timings |= reg & 0x80000000;		/* preserve PIO format bit */
 	if (unit == 0) {			/* are we configuring drive0? */
-		hwif->OUTL(timings, basereg+4);	/* write drive0 config register */
+		outl(timings, basereg + 4);	/* write drive0 config register */
 	} else {
 		if (timings & 0x00100000)
 			reg |=  0x00100000;	/* enable UDMA timings for both drives */
 		else
 			reg &= ~0x00100000;	/* disable UDMA timings for both drives */
-		hwif->OUTL(reg,     basereg+4);	/* write drive0 config register */
-		hwif->OUTL(timings, basereg+12);	/* write drive1 config register */
+		outl(reg, basereg + 4);		/* write drive0 config register */
+		outl(timings, basereg + 12);	/* write drive1 config register */
 	}
-	(void) hwif->ide_dma_host_on(drive);
-	/* set DMA_capable bit */
 
-	/*
-	 * Finally, turn DMA on in software, and exit.
-	 */
-	return hwif->ide_dma_on(drive);	/* success */
+	return 0;	/* success */
 }
 
 /**
@@ -321,17 +312,17 @@
 
 	hwif->tuneproc = &cs5530_tuneproc;
 	basereg = CS5530_BASEREG(hwif);
-	d0_timings = hwif->INL(basereg+0);
+	d0_timings = inl(basereg + 0);
 	if (CS5530_BAD_PIO(d0_timings)) {
 		/* PIO timings not initialized? */
-		hwif->OUTL(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+0);
+		outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 0);
 		if (!hwif->drives[0].autotune)
 			hwif->drives[0].autotune = 1;
 			/* needs autotuning later */
 	}
-	if (CS5530_BAD_PIO(hwif->INL(basereg+8))) {
-	/* PIO timings not initialized? */
-		hwif->OUTL(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+8);
+	if (CS5530_BAD_PIO(inl(basereg + 8))) {
+		/* PIO timings not initialized? */
+		outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 8);
 		if (!hwif->drives[1].autotune)
 			hwif->drives[1].autotune = 1;
 			/* needs autotuning later */
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
index 5c5aec2..45f43ef 100644
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -195,28 +195,19 @@
 
 static int cs5535_dma_check(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
-	struct hd_driveid *id	= drive->id;
 	u8 speed;
 
 	drive->init_speed = 0;
 
-	if ((id->capability & 1) && drive->autodma) {
-		if (ide_use_dma(drive)) {
-			if (cs5535_config_drive_for_dma(drive))
-				return hwif->ide_dma_on(drive);
-		}
+	if (ide_use_dma(drive) && cs5535_config_drive_for_dma(drive))
+		return 0;
 
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
+	if (ide_use_fast_pio(drive)) {
 		speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
 		cs5535_set_drive(drive, speed);
-		return hwif->ide_dma_off_quietly(drive);
 	}
-	/* IORDY not supported */
-	return 0;
+
+	return -1;
 }
 
 static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 9eafcbf..103b9db 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -197,8 +197,8 @@
 #if CY82C693_DEBUG_LOGS
 	/* for debug let's show the previous values */
 
-	HWIF(drive)->OUTB(index, CY82_INDEX_PORT);
-	data = HWIF(drive)->INB(CY82_DATA_PORT);
+	outb(index, CY82_INDEX_PORT);
+	data = inb(CY82_DATA_PORT);
 
 	printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n",
 		drive->name, HWIF(drive)->channel, drive->select.b.unit,
@@ -207,8 +207,8 @@
 
 	data = (u8)mode|(u8)(single<<2);
 
-	HWIF(drive)->OUTB(index, CY82_INDEX_PORT);
-	HWIF(drive)->OUTB(data, CY82_DATA_PORT);
+	outb(index, CY82_INDEX_PORT);
+	outb(data, CY82_DATA_PORT);
 
 #if CY82C693_DEBUG_INFO
 	printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n",
@@ -227,8 +227,8 @@
 	 */
 
 	data = BUSMASTER_TIMEOUT;
-	HWIF(drive)->OUTB(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT);
-	HWIF(drive)->OUTB(data, CY82_DATA_PORT);
+	outb(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT);
+	outb(data, CY82_DATA_PORT);
 
 #if CY82C693_DEBUG_INFO	
 	printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n",
@@ -478,21 +478,18 @@
 	}
 }
 
-static ide_pci_device_t cy82c693_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "CY82C693",
-		.init_chipset	= init_chipset_cy82c693,
-		.init_iops	= init_iops_cy82c693,
-		.init_hwif	= init_hwif_cy82c693,
-		.channels	= 1,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-	}
+static ide_pci_device_t cy82c693_chipset __devinitdata = {
+	.name		= "CY82C693",
+	.init_chipset	= init_chipset_cy82c693,
+	.init_iops	= init_iops_cy82c693,
+	.init_hwif	= init_hwif_cy82c693,
+	.channels	= 1,
+	.autodma	= AUTODMA,
+	.bootable	= ON_BOARD,
 };
 
 static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_pci_device_t *d = &cy82c693_chipsets[id->driver_data];
 	struct pci_dev *dev2;
 	int ret = -ENODEV;
 
@@ -501,7 +498,7 @@
         if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
 	    PCI_FUNC(dev->devfn) == 1) {
 		dev2 = pci_get_slot(dev->bus, dev->devfn + 1);
-		ret = ide_setup_pci_devices(dev, dev2, d);
+		ret = ide_setup_pci_devices(dev, dev2, &cy82c693_chipset);
 		/* We leak pci refs here but thats ok - we can't be unloaded */
 	}
 	return ret;
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index ce7b08f..924eaa3 100644
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -48,19 +48,6 @@
 	return 1;
 }
 
-static void hpt34x_clear_chipset (ide_drive_t *drive)
-{
-	struct pci_dev *dev	= HWIF(drive)->pci_dev;
-	u32 reg1 = 0, tmp1 = 0, reg2 = 0, tmp2 = 0;
-
-	pci_read_config_dword(dev, 0x44, &reg1);
-	pci_read_config_dword(dev, 0x48, &reg2);
-	tmp1 = ((0x00 << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
-	tmp2 = (reg2 & ~(0x11 << drive->dn));
-	pci_write_config_dword(dev, 0x44, tmp1);
-	pci_write_config_dword(dev, 0x48, tmp2);
-}
-
 static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
 {
 	struct pci_dev *dev	= HWIF(drive)->pci_dev;
@@ -81,7 +68,7 @@
 	pci_read_config_dword(dev, 0x44, &reg1);
 	pci_read_config_dword(dev, 0x48, &reg2);
 	tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
-	tmp2 = ((hi_speed << drive->dn) | reg2);
+	tmp2 = ((hi_speed << drive->dn) | (reg2 & ~(0x11 << drive->dn)));
 	pci_write_config_dword(dev, 0x44, tmp1);
 	pci_write_config_dword(dev, 0x48, tmp2);
 
@@ -99,7 +86,6 @@
 static void hpt34x_tune_drive (ide_drive_t *drive, u8 pio)
 {
 	pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
-	hpt34x_clear_chipset(drive);
 	(void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio));
 }
 
@@ -117,38 +103,25 @@
 	if (!(speed))
 		return 0;
 
-	hpt34x_clear_chipset(drive);
 	(void) hpt34x_tune_chipset(drive, speed);
 	return ide_dma_enable(drive);
 }
 
 static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
-
 	drive->init_speed = 0;
 
-	if (id && (id->capability & 1) && drive->autodma) {
-
-		if (ide_use_dma(drive)) {
-			if (config_chipset_for_dma(drive))
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
 #ifndef CONFIG_HPT34X_AUTODMA
-				return hwif->ide_dma_off_quietly(drive);
+		return -1;
 #else
-				return hwif->ide_dma_on(drive);
+		return 0;
 #endif
-		}
 
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
+	if (ide_use_fast_pio(drive))
 		hpt34x_tune_drive(drive, 255);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return -1;
 }
 
 /*
@@ -209,7 +182,6 @@
 
 	hwif->tuneproc = &hpt34x_tune_drive;
 	hwif->speedproc = &hpt34x_tune_chipset;
-	hwif->no_dsc = 1;
 	hwif->drives[0].autotune = 1;
 	hwif->drives[1].autotune = 1;
 
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 05be8fa..60ecdc2 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -736,24 +736,15 @@
 
 static int hpt366_config_drive_xfer_rate(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
-
 	drive->init_speed = 0;
 
-	if ((id->capability & 1) && drive->autodma) {
-		if (ide_use_dma(drive) && config_chipset_for_dma(drive))
-			return hwif->ide_dma_on(drive);
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
+	if (ide_use_fast_pio(drive))
 		hpt3xx_tune_drive(drive, 255);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return -1;
 }
 
 /*
@@ -841,7 +832,7 @@
 		return 0;
 	}
 
-	dma_stat = hwif->INB(hwif->dma_status);
+	dma_stat = inb(hwif->dma_status);
 	/* return 1 if INTR asserted */
 	if (dma_stat & 4)
 		return 1;
@@ -1391,9 +1382,6 @@
 	u8 dma_new	= 0, dma_old	= 0;
 	unsigned long flags;
 
-	if (!dmabase)
-		return;
-		
 	dma_old = hwif->INB(dmabase + 2);
 
 	local_irq_save(flags);
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c
index 63248b6..424f00b 100644
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -244,17 +244,15 @@
 
 static int it8213_config_drive_for_dma (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
+	u8 pio;
 
-	if (ide_use_dma(drive)) {
-		if (config_chipset_for_dma(drive))
-			return hwif->ide_dma_on(drive);
-	}
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-	hwif->speedproc(drive, XFER_PIO_0
-			+ ide_get_best_pio_mode(drive, 255, 4, NULL));
+	pio = ide_get_best_pio_mode(drive, 255, 4, NULL);
+	it8213_tune_chipset(drive, XFER_PIO_0 + pio);
 
- 	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 /**
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index e9bad18..a132767 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -520,14 +520,12 @@
 
 static int it821x_config_drive_for_dma (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-	if (ide_use_dma(drive)) {
-		if (config_chipset_for_dma(drive))
-			return hwif->ide_dma_on(drive);
-	}
 	config_it821x_chipset_for_pio(drive, 1);
-	return hwif->ide_dma_off_quietly(drive);
+
+	return -1;
 }
 
 /**
@@ -608,11 +606,11 @@
 				printk(".\n");
 			/* Now the core code will have wrongly decided no DMA
 			   so we need to fix this */
-			hwif->ide_dma_off_quietly(drive);
+			hwif->dma_off_quietly(drive);
 #ifdef CONFIG_IDEDMA_ONLYDISK
 			if (drive->media == ide_disk)
 #endif
-				hwif->ide_dma_check(drive);
+				ide_set_dma(drive);
 		} else {
 			/* Non RAID volume. Fixups to stop the core code
 			   doing unsupported things */
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
index f07bbbe..53f2550 100644
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -147,7 +147,9 @@
 {
 	u8 speed	= ide_dma_speed(drive, jmicron_ratemask(drive));
 
-	config_jmicron_chipset_for_pio(drive, !speed);
+	if (!speed)
+		return 0;
+
 	jmicron_tune_chipset(drive, speed);
 	return ide_dma_enable(drive);
 }
@@ -162,14 +164,12 @@
 
 static int jmicron_config_drive_for_dma (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= drive->hwif;
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-	if (ide_use_dma(drive)) {
-		if (config_chipset_for_dma(drive))
-			return hwif->ide_dma_on(drive);
-	}
 	config_jmicron_chipset_for_pio(drive, 1);
-	return hwif->ide_dma_off_quietly(drive);
+
+	return -1;
 }
 
 /**
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
index 8aaea4e..b310c4f 100644
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -166,10 +166,10 @@
 	/* get dma command mode */
 	dma_cmd = hwif->INB(hwif->dma_command);
 	/* stop DMA */
-	hwif->OUTB(dma_cmd & ~1, hwif->dma_command);
+	outb(dma_cmd & ~1, hwif->dma_command);
 	/* from ERRATA: clear the INTR & ERROR bits */
 	dma_cmd = hwif->INB(hwif->dma_command);
-	hwif->OUTB(dma_cmd|6, hwif->dma_command);
+	outb(dma_cmd | 6, hwif->dma_command);
 	/* and free any DMA resources */
 	ide_destroy_dmatable(drive);
 	/* verify good DMA status */
@@ -190,7 +190,8 @@
 static int ns87415_ide_dma_check (ide_drive_t *drive)
 {
 	if (drive->media != ide_disk)
-		return HWIF(drive)->ide_dma_off_quietly(drive);
+		return -1;
+
 	return __ide_dma_check(drive);
 }
 
@@ -243,9 +244,9 @@
 		 *      to SELECT_DRIVE() properly during first probe_hwif().
 		 */
 		timeout = 10000;
-		hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
+		outb(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
 		udelay(10);
-		hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
+		outb(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
 		do {
 			udelay(50);
 			stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
@@ -263,7 +264,7 @@
 	if (!hwif->dma_base)
 		return;
 
-	hwif->OUTB(0x60, hwif->dma_status);
+	outb(0x60, hwif->dma_status);
 	hwif->dma_setup = &ns87415_ide_dma_setup;
 	hwif->ide_dma_check = &ns87415_ide_dma_check;
 	hwif->ide_dma_end = &ns87415_ide_dma_end;
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
index 22bbf61..9ca60dd 100644
--- a/drivers/ide/pci/opti621.c
+++ b/drivers/ide/pci/opti621.c
@@ -176,34 +176,35 @@
 	return ((time*bus_speed+999)/1000);
 }
 
-static void write_reg(ide_hwif_t *hwif, u8 value, int reg)
 /* Write value to register reg, base of register
  * is at reg_base (0x1f0 primary, 0x170 secondary,
  * if not changed by PCI configuration).
  * This is from setupvic.exe program.
  */
+static void write_reg(u8 value, int reg)
 {
-	hwif->INW(reg_base+1);
-	hwif->INW(reg_base+1);
-	hwif->OUTB(3, reg_base+2);
-	hwif->OUTB(value, reg_base+reg);
-	hwif->OUTB(0x83, reg_base+2);
+	inw(reg_base + 1);
+	inw(reg_base + 1);
+	outb(3, reg_base + 2);
+	outb(value, reg_base + reg);
+	outb(0x83, reg_base + 2);
 }
 
-static u8 read_reg(ide_hwif_t *hwif, int reg)
 /* Read value from register reg, base of register
  * is at reg_base (0x1f0 primary, 0x170 secondary,
  * if not changed by PCI configuration).
  * This is from setupvic.exe program.
  */
+static u8 read_reg(int reg)
 {
 	u8 ret = 0;
 
-	hwif->INW(reg_base+1);
-	hwif->INW(reg_base+1);
-	hwif->OUTB(3, reg_base+2);
-	ret = hwif->INB(reg_base+reg);
-	hwif->OUTB(0x83, reg_base+2);
+	inw(reg_base + 1);
+	inw(reg_base + 1);
+	outb(3, reg_base + 2);
+	ret = inb(reg_base + reg);
+	outb(0x83, reg_base + 2);
+
 	return ret;
 }
 
@@ -286,39 +287,39 @@
      	reg_base = hwif->io_ports[IDE_DATA_OFFSET];
 
 	/* allow Register-B */
-	hwif->OUTB(0xc0, reg_base+CNTRL_REG);
+	outb(0xc0, reg_base + CNTRL_REG);
 	/* hmm, setupvic.exe does this ;-) */
-	hwif->OUTB(0xff, reg_base+5);
+	outb(0xff, reg_base + 5);
 	/* if reads 0xff, adapter not exist? */
-	(void) hwif->INB(reg_base+CNTRL_REG);
+	(void)inb(reg_base + CNTRL_REG);
 	/* if reads 0xc0, no interface exist? */
-	read_reg(hwif, CNTRL_REG);
+	read_reg(CNTRL_REG);
 	/* read version, probably 0 */
-	read_reg(hwif, STRAP_REG);
+	read_reg(STRAP_REG);
 
 	/* program primary drive */
-		/* select Index-0 for Register-A */
-	write_reg(hwif, 0,      MISC_REG);
-		/* set read cycle timings */
-	write_reg(hwif, cycle1, READ_REG);
-		/* set write cycle timings */
-	write_reg(hwif, cycle1, WRITE_REG);
+	/* select Index-0 for Register-A */
+	write_reg(0, MISC_REG);
+	/* set read cycle timings */
+	write_reg(cycle1, READ_REG);
+	/* set write cycle timings */
+	write_reg(cycle1, WRITE_REG);
 
 	/* program secondary drive */
-		/* select Index-1 for Register-B */
-	write_reg(hwif, 1,      MISC_REG);
-		/* set read cycle timings */
-	write_reg(hwif, cycle2, READ_REG);
-		/* set write cycle timings */
-	write_reg(hwif, cycle2, WRITE_REG);
+	/* select Index-1 for Register-B */
+	write_reg(1, MISC_REG);
+	/* set read cycle timings */
+	write_reg(cycle2, READ_REG);
+	/* set write cycle timings */
+	write_reg(cycle2, WRITE_REG);
 
 	/* use Register-A for drive 0 */
 	/* use Register-B for drive 1 */
-	write_reg(hwif, 0x85, CNTRL_REG);
+	write_reg(0x85, CNTRL_REG);
 
 	/* set address setup, DRDY timings,   */
 	/*  and read prefetch for both drives */
- 	write_reg(hwif, misc, MISC_REG);
+	write_reg(misc, MISC_REG);
 
 	spin_unlock_irqrestore(&ide_lock, flags);
 }
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 236a031..6ceb25b 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -101,8 +101,8 @@
 {
 	u8 value;
 
-	hwif->OUTB(index, hwif->dma_vendor1);
-	value = hwif->INB(hwif->dma_vendor3);
+	outb(index, hwif->dma_vendor1);
+	value = inb(hwif->dma_vendor3);
 
 	DBG("index[%02X] value[%02X]\n", index, value);
 	return value;
@@ -115,8 +115,8 @@
  */
 static void set_indexed_reg(ide_hwif_t *hwif, u8 index, u8 value)
 {
-	hwif->OUTB(index, hwif->dma_vendor1);
-	hwif->OUTB(value, hwif->dma_vendor3);
+	outb(index, hwif->dma_vendor1);
+	outb(value, hwif->dma_vendor3);
 	DBG("index[%02X] value[%02X]\n", index, value);
 }
 
@@ -281,25 +281,15 @@
 
 static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
-
 	drive->init_speed = 0;
 
-	if ((id->capability & 1) && drive->autodma) {
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-		if (ide_use_dma(drive) && config_chipset_for_dma(drive))
-			return hwif->ide_dma_on(drive);
+	if (ide_use_fast_pio(drive))
+		pdcnew_tune_drive(drive, 255);
 
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
-		hwif->tuneproc(drive, 255);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+	return -1;
 }
 
 static int pdcnew_quirkproc(ide_drive_t *drive)
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index 730e8d1..a7a639f 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -2,6 +2,7 @@
  *  linux/drivers/ide/pci/pdc202xx_old.c	Version 0.36	Sept 11, 2002
  *
  *  Copyright (C) 1998-2002		Andre Hedrick <andre@linux-ide.org>
+ *  Copyright (C) 2006-2007		MontaVista Software, Inc.
  *
  *  Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this
  *  compiled into the kernel if you have more than one card installed.
@@ -216,21 +217,10 @@
 }
 
 
-/*   0    1    2    3    4    5    6   7   8
- * 960, 480, 390, 300, 240, 180, 120, 90, 60
- *           180, 150, 120,  90,  60
- * DMA_Speed
- * 180, 120,  90,  90,  90,  60,  30
- *  11,   5,   4,   3,   2,   1,   0
- */
-static void config_chipset_for_pio (ide_drive_t *drive, u8 pio)
+static void pdc202xx_tune_drive(ide_drive_t *drive, u8 pio)
 {
-	u8 speed = 0;
-
-	if (pio == 5) pio = 4;
-	speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL);
-        
-	pdc202xx_tune_chipset(drive, speed);
+	pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+	pdc202xx_tune_chipset(drive, XFER_PIO_0 + pio);
 }
 
 static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
@@ -250,17 +240,17 @@
 static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif)
 {
 	unsigned long clock_reg = hwif->dma_master + 0x11;
-	u8 clock = hwif->INB(clock_reg);
+	u8 clock = inb(clock_reg);
 
-	hwif->OUTB(clock | (hwif->channel ? 0x08 : 0x02), clock_reg);
+	outb(clock | (hwif->channel ? 0x08 : 0x02), clock_reg);
 }
 
 static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif)
 {
 	unsigned long clock_reg = hwif->dma_master + 0x11;
-	u8 clock = hwif->INB(clock_reg);
+	u8 clock = inb(clock_reg);
 
-	hwif->OUTB(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
+	outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
 }
 
 static int config_chipset_for_dma (ide_drive_t *drive)
@@ -332,27 +322,15 @@
 
 static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
-
 	drive->init_speed = 0;
 
-	if (id && (id->capability & 1) && drive->autodma) {
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-		if (ide_use_dma(drive)) {
-			if (config_chipset_for_dma(drive))
-				return hwif->ide_dma_on(drive);
-		}
+	if (ide_use_fast_pio(drive))
+		pdc202xx_tune_drive(drive, 255);
 
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
-		hwif->tuneproc(drive, 5);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+	return -1;
 }
 
 static int pdc202xx_quirkproc (ide_drive_t *drive)
@@ -375,14 +353,14 @@
 		unsigned long high_16   = hwif->dma_master;
 		unsigned long atapi_reg	= high_16 + (hwif->channel ? 0x24 : 0x20);
 		u32 word_count	= 0;
-		u8 clock = hwif->INB(high_16 + 0x11);
+		u8 clock = inb(high_16 + 0x11);
 
-		hwif->OUTB(clock|(hwif->channel ? 0x08 : 0x02), high_16+0x11);
+		outb(clock | (hwif->channel ? 0x08 : 0x02), high_16 + 0x11);
 		word_count = (rq->nr_sectors << 8);
 		word_count = (rq_data_dir(rq) == READ) ?
 					word_count | 0x05000000 :
 					word_count | 0x06000000;
-		hwif->OUTL(word_count, atapi_reg);
+		outl(word_count, atapi_reg);
 	}
 	ide_dma_start(drive);
 }
@@ -395,9 +373,9 @@
 		unsigned long atapi_reg	= high_16 + (hwif->channel ? 0x24 : 0x20);
 		u8 clock		= 0;
 
-		hwif->OUTL(0, atapi_reg); /* zero out extra */
-		clock = hwif->INB(high_16 + 0x11);
-		hwif->OUTB(clock & ~(hwif->channel ? 0x08:0x02), high_16+0x11);
+		outl(0, atapi_reg); /* zero out extra */
+		clock = inb(high_16 + 0x11);
+		outb(clock & ~(hwif->channel ? 0x08:0x02), high_16 + 0x11);
 	}
 	if (drive->current_speed > XFER_UDMA_2)
 		pdc_old_disable_66MHz_clock(drive->hwif);
@@ -408,8 +386,8 @@
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	unsigned long high_16	= hwif->dma_master;
-	u8 dma_stat		= hwif->INB(hwif->dma_status);
-	u8 sc1d			= hwif->INB((high_16 + 0x001d));
+	u8 dma_stat		= inb(hwif->dma_status);
+	u8 sc1d			= inb(high_16 + 0x001d);
 
 	if (hwif->channel) {
 		/* bit7: Error, bit6: Interrupting, bit5: FIFO Full, bit4: FIFO Empty */
@@ -445,11 +423,11 @@
 static void pdc202xx_reset_host (ide_hwif_t *hwif)
 {
 	unsigned long high_16	= hwif->dma_master;
-	u8 udma_speed_flag	= hwif->INB(high_16|0x001f);
+	u8 udma_speed_flag	= inb(high_16 | 0x001f);
 
-	hwif->OUTB((udma_speed_flag | 0x10), (high_16|0x001f));
+	outb(udma_speed_flag | 0x10, high_16 | 0x001f);
 	mdelay(100);
-	hwif->OUTB((udma_speed_flag & ~0x10), (high_16|0x001f));
+	outb(udma_speed_flag & ~0x10, high_16 | 0x001f);
 	mdelay(2000);	/* 2 seconds ?! */
 
 	printk(KERN_WARNING "PDC202XX: %s channel reset.\n",
@@ -463,7 +441,7 @@
 	
 	pdc202xx_reset_host(hwif);
 	pdc202xx_reset_host(mate);
-	hwif->tuneproc(drive, 5);
+	pdc202xx_tune_drive(drive, 255);
 }
 
 static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev,
@@ -490,7 +468,7 @@
 		hwif->rqsize = 256;
 
 	hwif->autodma = 0;
-	hwif->tuneproc  = &config_chipset_for_pio;
+	hwif->tuneproc  = &pdc202xx_tune_drive;
 	hwif->quirkproc = &pdc202xx_quirkproc;
 
 	if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246)
@@ -537,9 +515,9 @@
 		return;
 	}
 
-	udma_speed_flag	= hwif->INB((dmabase|0x1f));
-	primary_mode	= hwif->INB((dmabase|0x1a));
-	secondary_mode	= hwif->INB((dmabase|0x1b));
+	udma_speed_flag	= inb(dmabase | 0x1f);
+	primary_mode	= inb(dmabase | 0x1a);
+	secondary_mode	= inb(dmabase | 0x1b);
 	printk(KERN_INFO "%s: (U)DMA Burst Bit %sABLED " \
 		"Primary %s Mode " \
 		"Secondary %s Mode.\n", hwif->cds->name,
@@ -552,30 +530,10 @@
 		printk(KERN_INFO "%s: FORCING BURST BIT 0x%02x->0x%02x ",
 			hwif->cds->name, udma_speed_flag,
 			(udma_speed_flag|1));
-		hwif->OUTB(udma_speed_flag|1,(dmabase|0x1f));
-		printk("%sACTIVE\n",
-			(hwif->INB(dmabase|0x1f)&1) ? "":"IN");
+		outb(udma_speed_flag | 1, dmabase | 0x1f);
+		printk("%sACTIVE\n", (inb(dmabase | 0x1f) & 1) ? "" : "IN");
 	}
 #endif /* CONFIG_PDC202XX_BURST */
-#ifdef CONFIG_PDC202XX_MASTER
-	if (!(primary_mode & 1)) {
-		printk(KERN_INFO "%s: FORCING PRIMARY MODE BIT "
-			"0x%02x -> 0x%02x ", hwif->cds->name,
-			primary_mode, (primary_mode|1));
-		hwif->OUTB(primary_mode|1, (dmabase|0x1a));
-		printk("%s\n",
-			(hwif->INB((dmabase|0x1a)) & 1) ? "MASTER" : "PCI");
-	}
-
-	if (!(secondary_mode & 1)) {
-		printk(KERN_INFO "%s: FORCING SECONDARY MODE BIT "
-			"0x%02x -> 0x%02x ", hwif->cds->name,
-			secondary_mode, (secondary_mode|1));
-		hwif->OUTB(secondary_mode|1, (dmabase|0x1b));
-		printk("%s\n",
-			(hwif->INB((dmabase|0x1b)) & 1) ? "MASTER" : "PCI");
-	}
-#endif /* CONFIG_PDC202XX_MASTER */
 
 	ide_setup_dma(hwif, dmabase, 8);
 }
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index 52cfc2a..569822f 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -369,7 +369,7 @@
 	 * If no DMA speed was available or the chipset has DMA bugs
 	 * then disable DMA and use PIO
 	 */
-	if (!speed || no_piix_dma)
+	if (!speed)
 		return 0;
 
 	(void) piix_tune_chipset(drive, speed);
@@ -386,41 +386,28 @@
  
 static int piix_config_drive_xfer_rate (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
-
 	drive->init_speed = 0;
 
-	if ((id->capability & 1) && drive->autodma) {
+	if (ide_use_dma(drive) && piix_config_drive_for_dma(drive))
+		return 0;
 
-		if (ide_use_dma(drive) && piix_config_drive_for_dma(drive))
-			return hwif->ide_dma_on(drive);
-
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
+	if (ide_use_fast_pio(drive))
 		/* Find best PIO mode. */
-		(void) hwif->speedproc(drive, XFER_PIO_0 +
-				       ide_get_best_pio_mode(drive, 255, 4, NULL));
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+		piix_tune_chipset(drive, XFER_PIO_0 +
+				  ide_get_best_pio_mode(drive, 255, 4, NULL));
+
+	return -1;
 }
 
 /**
- *	init_chipset_piix	-	set up the PIIX chipset
- *	@dev: PCI device to set up
- *	@name: Name of the device
+ *	piix_is_ichx	-	check if ICHx
+ *	@dev: PCI device to check
  *
- *	Initialize the PCI device as required. For the PIIX this turns
- *	out to be nice and simple
+ *	returns 1 if ICHx, 0 otherwise.
  */
- 
-static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name)
+static int piix_is_ichx(struct pci_dev *dev)
 {
-        switch(dev->device) {
+        switch (dev->device) {
 		case PCI_DEVICE_ID_INTEL_82801EB_1:
 		case PCI_DEVICE_ID_INTEL_82801AA_1:
 		case PCI_DEVICE_ID_INTEL_82801AB_1:
@@ -438,19 +425,61 @@
 		case PCI_DEVICE_ID_INTEL_ICH7_21:
 		case PCI_DEVICE_ID_INTEL_ESB2_18:
 		case PCI_DEVICE_ID_INTEL_ICH8_6:
-		{
-			unsigned int extra = 0;
-			pci_read_config_dword(dev, 0x54, &extra);
-			pci_write_config_dword(dev, 0x54, extra|0x400);
-		}
-		default:
-			break;
+			return 1;
 	}
 
 	return 0;
 }
 
 /**
+ *	init_chipset_piix	-	set up the PIIX chipset
+ *	@dev: PCI device to set up
+ *	@name: Name of the device
+ *
+ *	Initialize the PCI device as required. For the PIIX this turns
+ *	out to be nice and simple
+ */
+
+static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name)
+{
+	if (piix_is_ichx(dev)) {
+		unsigned int extra = 0;
+		pci_read_config_dword(dev, 0x54, &extra);
+		pci_write_config_dword(dev, 0x54, extra|0x400);
+	}
+
+	return 0;
+}
+
+/**
+ *	piix_dma_clear_irq	-	clear BMDMA status
+ *	@drive: IDE drive to clear
+ *
+ *	Called from ide_intr() for PIO interrupts
+ *	to clear BMDMA status as needed by ICHx
+ */
+static void piix_dma_clear_irq(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+	u8 dma_stat;
+
+	/* clear the INTR & ERROR bits */
+	dma_stat = hwif->INB(hwif->dma_status);
+	/* Should we force the bit as well ? */
+	hwif->OUTB(dma_stat, hwif->dma_status);
+}
+
+static int __devinit piix_cable_detect(ide_hwif_t *hwif)
+{
+	struct pci_dev *dev = hwif->pci_dev;
+	u8 reg54h = 0, mask = hwif->channel ? 0xc0 : 0x30;
+
+	pci_read_config_byte(dev, 0x54, &reg54h);
+
+	return (reg54h & mask) ? 1 : 0;
+}
+
+/**
  *	init_hwif_piix		-	fill in the hwif for the PIIX
  *	@hwif: IDE interface
  *
@@ -460,9 +489,6 @@
 
 static void __devinit init_hwif_piix(ide_hwif_t *hwif)
 {
-	u8 reg54h = 0, reg55h = 0, ata66 = 0;
-	u8 mask = hwif->channel ? 0xc0 : 0x30;
-
 #ifndef CONFIG_IA64
 	if (!hwif->irq)
 		hwif->irq = hwif->channel ? 15 : 14;
@@ -472,10 +498,6 @@
 		/* This is a painful system best to let it self tune for now */
 		return;
 	}
-	/* ESB2 appears to generate spurious DMA interrupts in PIO mode
-	   when in native mode */
-	if (hwif->pci_dev->device == PCI_DEVICE_ID_INTEL_ESB2_18)
-		hwif->atapi_irq_bogon = 1;
 
 	hwif->autodma = 0;
 	hwif->tuneproc = &piix_tune_drive;
@@ -486,15 +508,16 @@
 	if (!hwif->dma_base)
 		return;
 
+	/* ICHx need to clear the bmdma status for all interrupts */
+	if (piix_is_ichx(hwif->pci_dev))
+		hwif->ide_dma_clear_irq = &piix_dma_clear_irq;
+
 	hwif->atapi_dma = 1;
 	hwif->ultra_mask = 0x3f;
 	hwif->mwdma_mask = 0x06;
 	hwif->swdma_mask = 0x04;
 
 	switch(hwif->pci_dev->device) {
-		case PCI_DEVICE_ID_INTEL_82371MX:
-			hwif->mwdma_mask = 0x80;
-			hwif->swdma_mask = 0x80;
 		case PCI_DEVICE_ID_INTEL_82371FB_0:
 		case PCI_DEVICE_ID_INTEL_82371FB_1:
 		case PCI_DEVICE_ID_INTEL_82371SB_1:
@@ -507,14 +530,14 @@
 			hwif->ultra_mask = 0x07;
 			break;
 		default:
-			pci_read_config_byte(hwif->pci_dev, 0x54, &reg54h);
-			pci_read_config_byte(hwif->pci_dev, 0x55, &reg55h);
-			ata66 = (reg54h & mask) ? 1 : 0;
+			if (!hwif->udma_four)
+				hwif->udma_four = piix_cable_detect(hwif);
 			break;
 	}
 
-	if (!(hwif->udma_four))
-		hwif->udma_four = ata66;
+	if (no_piix_dma)
+		hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0;
+
 	hwif->ide_dma_check = &piix_config_drive_xfer_rate;
 	if (!noautodma)
 		hwif->autodma = 1;
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index 8d762d3..b5ae0c5 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -161,7 +161,7 @@
 	/*
 	 * Default to DMA-off in case we run into trouble here.
 	 */
-	hwif->ide_dma_off_quietly(drive);			/* turn off DMA while we fiddle */
+	hwif->dma_off_quietly(drive);	/* turn off DMA while we fiddle */
 	outb(inb(hwif->dma_base+2)&~(unit?0x40:0x20), hwif->dma_base+2); /* clear DMA_capable bit */
 
 	/*
@@ -241,10 +241,7 @@
 
 	outb(inb(hwif->dma_base+2)|(unit?0x40:0x20), hwif->dma_base+2);	/* set DMA_capable bit */
 
-	/*
-	 * Finally, turn DMA on in software, and exit.
-	 */
-	return hwif->ide_dma_on(drive);	/* success */
+	return 0;	/* success */
 }
 
 /*
@@ -442,10 +439,10 @@
 			ide_drive_t *drive = &(hwif->drives[d]);
 			if (drive->present && !__ide_dma_bad_drive(drive)) {
 				int was_using_dma = drive->using_dma;
-				hwif->ide_dma_off_quietly(drive);
+				hwif->dma_off_quietly(drive);
 				sc1200_config_dma(drive);
 				if (!was_using_dma && drive->using_dma) {
-					hwif->ide_dma_off_quietly(drive);
+					hwif->dma_off_quietly(drive);
 				}
 			}
 		}
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index ea9a28a..dbcd37a 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -160,7 +160,7 @@
 	if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
 	    (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) {
 		if (!drive->init_speed) {
-			u8 dma_stat = hwif->INB(hwif->dma_status);
+			u8 dma_stat = inb(hwif->dma_status);
 
 dma_pio:
 			if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) &&
@@ -315,35 +315,15 @@
 
 static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
-
 	drive->init_speed = 0;
 
-	if ((id->capability & 1) && drive->autodma) {
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-		if (ide_use_dma(drive)) {
-			if (config_chipset_for_dma(drive))
-				return hwif->ide_dma_on(drive);
-		}
-
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
+	if (ide_use_fast_pio(drive))
 		config_chipset_for_pio(drive);
-		//	hwif->tuneproc(drive, 5);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
-}
 
-/* This can go soon */
-
-static int svwks_ide_dma_end (ide_drive_t *drive)
-{
-	return __ide_dma_end(drive);
+	return -1;
 }
 
 static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const char *name)
@@ -537,35 +517,20 @@
 	}
 
 	hwif->ide_dma_check = &svwks_config_drive_xfer_rate;
-	if (hwif->pci_dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE)
-		hwif->ide_dma_end = &svwks_ide_dma_end;
-	else if (!(hwif->udma_four))
-		hwif->udma_four = ata66_svwks(hwif);
+	if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
+		if (!hwif->udma_four)
+			hwif->udma_four = ata66_svwks(hwif);
+	}
 	if (!noautodma)
 		hwif->autodma = 1;
 
-	dma_stat = hwif->INB(hwif->dma_status);
+	dma_stat = inb(hwif->dma_status);
 	hwif->drives[0].autodma = (dma_stat & 0x20);
 	hwif->drives[1].autodma = (dma_stat & 0x40);
 	hwif->drives[0].autotune = (!(dma_stat & 0x20));
 	hwif->drives[1].autotune = (!(dma_stat & 0x40));
 }
 
-/*
- * We allow the BM-DMA driver to only work on enabled interfaces.
- */
-static void __devinit init_dma_svwks (ide_hwif_t *hwif, unsigned long dmabase)
-{
-	struct pci_dev *dev = hwif->pci_dev;
-
-	if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
-	     (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) &&
-	    (!(PCI_FUNC(dev->devfn) & 1)) && (hwif->channel))
-		return;
-
-	ide_setup_dma(hwif, dmabase, 8);
-}
-
 static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d)
 {
 	return ide_setup_pci_device(dev, d);
@@ -600,7 +565,6 @@
 		.init_setup	= init_setup_svwks,
 		.init_chipset	= init_chipset_svwks,
 		.init_hwif	= init_hwif_svwks,
-		.init_dma	= init_dma_svwks,
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.bootable	= ON_BOARD,
@@ -609,7 +573,6 @@
 		.init_setup	= init_setup_csb6,
 		.init_chipset	= init_chipset_svwks,
 		.init_hwif	= init_hwif_svwks,
-		.init_dma	= init_dma_svwks,
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.bootable	= ON_BOARD,
@@ -618,7 +581,6 @@
 		.init_setup	= init_setup_csb6,
 		.init_chipset	= init_chipset_svwks,
 		.init_hwif	= init_hwif_svwks,
-		.init_dma	= init_dma_svwks,
 		.channels	= 1,	/* 2 */
 		.autodma	= AUTODMA,
 		.bootable	= ON_BOARD,
@@ -627,7 +589,6 @@
 		.init_setup	= init_setup_svwks,
 		.init_chipset	= init_chipset_svwks,
 		.init_hwif	= init_hwif_svwks,
-		.init_dma	= init_dma_svwks,
 		.channels	= 1,	/* 2 */
 		.autodma	= AUTODMA,
 		.bootable	= ON_BOARD,
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index b0bf018..fd09b29 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -110,24 +110,24 @@
 static void
 sgiioc4_maskproc(ide_drive_t * drive, int mask)
 {
-	ide_hwif_t *hwif = HWIF(drive);
-	hwif->OUTB(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
-		   IDE_CONTROL_REG);
+	writeb(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
+	       (void __iomem *)IDE_CONTROL_REG);
 }
 
 
 static int
 sgiioc4_checkirq(ide_hwif_t * hwif)
 {
-	u8 intr_reg =
-	    hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4);
+	unsigned long intr_addr =
+		hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4;
 
-	if (intr_reg & 0x03)
+	if ((u8)readl((void __iomem *)intr_addr) & 0x03)
 		return 1;
 
 	return 0;
 }
 
+static u8 sgiioc4_INB(unsigned long);
 
 static int
 sgiioc4_clearirq(ide_drive_t * drive)
@@ -138,21 +138,21 @@
 	    hwif->io_ports[IDE_IRQ_OFFSET] + (IOC4_INTR_REG << 2);
 
 	/* Code to check for PCI error conditions */
-	intr_reg = hwif->INL(other_ir);
+	intr_reg = readl((void __iomem *)other_ir);
 	if (intr_reg & 0x03) { /* Valid IOC4-IDE interrupt */
 		/*
-		 * Using hwif->INB to read the IDE_STATUS_REG has a side effect
+		 * Using sgiioc4_INB to read the IDE_STATUS_REG has a side effect
 		 * of clearing the interrupt.  The first read should clear it
 		 * if it is set.  The second read should return a "clear" status
 		 * if it got cleared.  If not, then spin for a bit trying to
 		 * clear it.
 		 */
-		u8 stat = hwif->INB(IDE_STATUS_REG);
+		u8 stat = sgiioc4_INB(IDE_STATUS_REG);
 		int count = 0;
-		stat = hwif->INB(IDE_STATUS_REG);
+		stat = sgiioc4_INB(IDE_STATUS_REG);
 		while ((stat & 0x80) && (count++ < 100)) {
 			udelay(1);
-			stat = hwif->INB(IDE_STATUS_REG);
+			stat = sgiioc4_INB(IDE_STATUS_REG);
 		}
 
 		if (intr_reg & 0x02) {
@@ -161,9 +161,9 @@
 			    pci_stat_cmd_reg;
 
 			pci_err_addr_low =
-				hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET]);
+				readl((void __iomem *)hwif->io_ports[IDE_IRQ_OFFSET]);
 			pci_err_addr_high =
-				hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + 4);
+				readl((void __iomem *)(hwif->io_ports[IDE_IRQ_OFFSET] + 4));
 			pci_read_config_dword(hwif->pci_dev, PCI_COMMAND,
 					      &pci_stat_cmd_reg);
 			printk(KERN_ERR
@@ -180,9 +180,9 @@
 		}
 
 		/* Clear the Interrupt, Error bits on the IOC4 */
-		hwif->OUTL(0x03, other_ir);
+		writel(0x03, (void __iomem *)other_ir);
 
-		intr_reg = hwif->INL(other_ir);
+		intr_reg = readl((void __iomem *)other_ir);
 	}
 
 	return intr_reg & 3;
@@ -191,23 +191,25 @@
 static void sgiioc4_ide_dma_start(ide_drive_t * drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
-	unsigned int reg = hwif->INL(hwif->dma_base + IOC4_DMA_CTRL * 4);
+	unsigned long ioc4_dma_addr = hwif->dma_base + IOC4_DMA_CTRL * 4;
+	unsigned int reg = readl((void __iomem *)ioc4_dma_addr);
 	unsigned int temp_reg = reg | IOC4_S_DMA_START;
 
-	hwif->OUTL(temp_reg, hwif->dma_base + IOC4_DMA_CTRL * 4);
+	writel(temp_reg, (void __iomem *)ioc4_dma_addr);
 }
 
 static u32
 sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base)
 {
+	unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
 	u32	ioc4_dma;
 	int	count;
 
 	count = 0;
-	ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
+	ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
 	while ((ioc4_dma & IOC4_S_DMA_STOP) && (count++ < 200)) {
 		udelay(1);
-		ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
+		ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
 	}
 	return ioc4_dma;
 }
@@ -218,11 +220,11 @@
 {
 	u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0;
 	ide_hwif_t *hwif = HWIF(drive);
-	u64 dma_base = hwif->dma_base;
+	unsigned long dma_base = hwif->dma_base;
 	int dma_stat = 0;
 	unsigned long *ending_dma = ide_get_hwifdata(hwif);
 
-	hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
+	writel(IOC4_S_DMA_STOP, (void __iomem *)(dma_base + IOC4_DMA_CTRL * 4));
 
 	ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
 
@@ -254,8 +256,8 @@
 		dma_stat = 1;
 	}
 
-	bc_dev = hwif->INL(dma_base + IOC4_BC_DEV * 4);
-	bc_mem = hwif->INL(dma_base + IOC4_BC_MEM * 4);
+	bc_dev = readl((void __iomem *)(dma_base + IOC4_BC_DEV * 4));
+	bc_mem = readl((void __iomem *)(dma_base + IOC4_BC_MEM * 4));
 
 	if ((bc_dev & 0x01FF) || (bc_mem & 0x1FF)) {
 		if (bc_dev > bc_mem + 8) {
@@ -273,34 +275,29 @@
 }
 
 static int
-sgiioc4_ide_dma_check(ide_drive_t * drive)
-{
-	if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
-		printk(KERN_INFO
-		       "Couldnot set %s in Multimode-2 DMA mode | "
-			   "Drive %s using PIO instead\n",
-		       drive->name, drive->name);
-		drive->using_dma = 0;
-	} else
-		drive->using_dma = 1;
-
-	return 0;
-}
-
-static int
 sgiioc4_ide_dma_on(ide_drive_t * drive)
 {
 	drive->using_dma = 1;
 
-	return HWIF(drive)->ide_dma_host_on(drive);
+	return 0;
 }
 
-static int
-sgiioc4_ide_dma_off_quietly(ide_drive_t * drive)
+static void sgiioc4_dma_off_quietly(ide_drive_t *drive)
 {
 	drive->using_dma = 0;
 
-	return HWIF(drive)->ide_dma_host_off(drive);
+	drive->hwif->dma_host_off(drive);
+}
+
+static int sgiioc4_ide_dma_check(ide_drive_t *drive)
+{
+	/* FIXME: check for available DMA modes */
+	if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
+		printk(KERN_WARNING "%s: couldn't set MWDMA2 mode, "
+				    "using PIO instead\n", drive->name);
+		return -1;
+	} else
+		return 0;
 }
 
 /* returns 1 if dma irq issued, 0 otherwise */
@@ -310,21 +307,13 @@
 	return sgiioc4_checkirq(HWIF(drive));
 }
 
-static int
-sgiioc4_ide_dma_host_on(ide_drive_t * drive)
+static void sgiioc4_dma_host_on(ide_drive_t * drive)
 {
-	if (drive->using_dma)
-		return 0;
-
-	return 1;
 }
 
-static int
-sgiioc4_ide_dma_host_off(ide_drive_t * drive)
+static void sgiioc4_dma_host_off(ide_drive_t * drive)
 {
 	sgiioc4_clearirq(drive);
-
-	return 0;
 }
 
 static int
@@ -436,16 +425,17 @@
 {
 	u32 ioc4_dma;
 	ide_hwif_t *hwif = HWIF(drive);
-	u64 dma_base = hwif->dma_base;
+	unsigned long dma_base = hwif->dma_base;
+	unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
 	u32 dma_addr, ending_dma_addr;
 
-	ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
+	ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
 
 	if (ioc4_dma & IOC4_S_DMA_ACTIVE) {
 		printk(KERN_WARNING
 			"%s(%s):Warning!! DMA from previous transfer was still active\n",
 		       __FUNCTION__, drive->name);
-		hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
+		writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
 		ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
 
 		if (ioc4_dma & IOC4_S_DMA_STOP)
@@ -454,13 +444,13 @@
 			       __FUNCTION__, drive->name);
 	}
 
-	ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
+	ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
 	if (ioc4_dma & IOC4_S_DMA_ERROR) {
 		printk(KERN_WARNING
 		       "%s(%s) : Warning!! - DMA Error during Previous"
 		       " transfer | status 0x%x\n",
 		       __FUNCTION__, drive->name, ioc4_dma);
-		hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
+		writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
 		ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
 
 		if (ioc4_dma & IOC4_S_DMA_STOP)
@@ -471,14 +461,14 @@
 
 	/* Address of the Scatter Gather List */
 	dma_addr = cpu_to_le32(hwif->dmatable_dma);
-	hwif->OUTL(dma_addr, dma_base + IOC4_DMA_PTR_L * 4);
+	writel(dma_addr, (void __iomem *)(dma_base + IOC4_DMA_PTR_L * 4));
 
 	/* Address of the Ending DMA */
 	memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE);
 	ending_dma_addr = cpu_to_le32(hwif->dma_status);
-	hwif->OUTL(ending_dma_addr, dma_base + IOC4_DMA_END_ADDR * 4);
+	writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
 
-	hwif->OUTL(dma_direction, dma_base + IOC4_DMA_CTRL * 4);
+	writel(dma_direction, (void __iomem *)ioc4_dma_addr);
 	drive->waiting_for_dma = 1;
 }
 
@@ -590,7 +580,7 @@
 static void __devinit
 ide_init_sgiioc4(ide_hwif_t * hwif)
 {
-	hwif->mmio = 2;
+	hwif->mmio = 1;
 	hwif->autodma = 1;
 	hwif->atapi_dma = 1;
 	hwif->ultra_mask = 0x0;	/* Disable Ultra DMA */
@@ -613,10 +603,10 @@
 	hwif->ide_dma_end = &sgiioc4_ide_dma_end;
 	hwif->ide_dma_check = &sgiioc4_ide_dma_check;
 	hwif->ide_dma_on = &sgiioc4_ide_dma_on;
-	hwif->ide_dma_off_quietly = &sgiioc4_ide_dma_off_quietly;
+	hwif->dma_off_quietly = &sgiioc4_dma_off_quietly;
 	hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
-	hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on;
-	hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off;
+	hwif->dma_host_on = &sgiioc4_dma_host_on;
+	hwif->dma_host_off = &sgiioc4_dma_host_off;
 	hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
 	hwif->ide_dma_timeout = &__ide_dma_timeout;
 
@@ -688,7 +678,7 @@
 	default_hwif_mmiops(hwif);
 
 	/* Initializing chipset IRQ Registers */
-	hwif->OUTL(0x03, irqport + IOC4_INTR_SET * 4);
+	writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));
 
 	ide_init_sgiioc4(hwif);
 
@@ -729,8 +719,7 @@
 	return ret;
 }
 
-static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = {
-	{
+static ide_pci_device_t sgiioc4_chipset __devinitdata = {
 	 /* Channel 0 */
 	 .name = "SGIIOC4",
 	 .init_hwif = ide_init_sgiioc4,
@@ -739,7 +728,6 @@
 	 .autodma = AUTODMA,
 	 /* SGI IOC4 doesn't have enablebits. */
 	 .bootable = ON_BOARD,
-	}
 };
 
 int
@@ -751,8 +739,7 @@
 	if (idd->idd_variant == IOC4_VARIANT_PCI_RT)
 		return 0;
 
-	return pci_init_sgiioc4(idd->idd_pdev,
-				&sgiioc4_chipsets[idd->idd_pci_id->driver_data]);
+	return pci_init_sgiioc4(idd->idd_pdev, &sgiioc4_chipset);
 }
 
 static struct ioc4_submodule ioc4_ide_submodule = {
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 4ff89c7..7b4c189 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -1,8 +1,9 @@
 /*
- * linux/drivers/ide/pci/siimage.c		Version 1.07	Nov 30, 2003
+ * linux/drivers/ide/pci/siimage.c		Version 1.11	Jan 27, 2007
  *
  * Copyright (C) 2001-2002	Andre Hedrick <andre@linux-ide.org>
  * Copyright (C) 2003		Red Hat <alan@redhat.com>
+ * Copyright (C) 2007		MontaVista Software, Inc.
  *
  *  May be copied or modified under the terms of the GNU General Public License
  *
@@ -205,41 +206,39 @@
 	unsigned long tfaddr	= siimage_selreg(hwif, 0x02);
 	
 	/* cheat for now and use the docs */
-	switch(mode_wanted) {
-		case 4:	
-			speedp = 0x10c1; 
-			speedt = 0x10c1;
-			break;
-		case 3:	
-			speedp = 0x10C3; 
-			speedt = 0x10C3;
-			break;
-		case 2:	
-			speedp = 0x1104; 
-			speedt = 0x1281;
-			break;
-		case 1:		
-			speedp = 0x2283; 
-			speedt = 0x1281;
-			break;
-		case 0:
-		default:
-			speedp = 0x328A; 
-			speedt = 0x328A;
-			break;
+	switch (mode_wanted) {
+	case 4:
+		speedp = 0x10c1;
+		speedt = 0x10c1;
+		break;
+	case 3:
+		speedp = 0x10c3;
+		speedt = 0x10c3;
+		break;
+	case 2:
+		speedp = 0x1104;
+		speedt = 0x1281;
+		break;
+	case 1:
+		speedp = 0x2283;
+		speedt = 0x2283;
+		break;
+	case 0:
+	default:
+		speedp = 0x328a;
+		speedt = 0x328a;
+		break;
 	}
-	if (hwif->mmio)
-	{
-		hwif->OUTW(speedt, addr);
-		hwif->OUTW(speedp, tfaddr);
+
+	if (hwif->mmio) {
+		hwif->OUTW(speedp, addr);
+		hwif->OUTW(speedt, tfaddr);
 		/* Now set up IORDY */
 		if(mode_wanted == 3 || mode_wanted == 4)
 			hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2);
 		else
 			hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2);
-	}
-	else
-	{
+	} else {
 		pci_write_config_word(hwif->pci_dev, addr, speedp);
 		pci_write_config_word(hwif->pci_dev, tfaddr, speedt);
 		pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp);
@@ -397,12 +396,9 @@
 	if (!speed)
 		return 0;
 
-	if (ide_set_xfer_rate(drive, speed))
+	if (siimage_tune_chipset(drive, speed))
 		return 0;
 
-	if (!drive->init_speed)
-		drive->init_speed = speed;
-
 	return ide_dma_enable(drive);
 }
 
@@ -418,25 +414,13 @@
  
 static int siimage_config_drive_for_dma (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-	if ((id->capability & 1) != 0 && drive->autodma) {
-
-		if (ide_use_dma(drive)) {
-			if (config_chipset_for_dma(drive))
-				return hwif->ide_dma_on(drive);
-		}
-
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
+	if (ide_use_fast_pio(drive))
 		config_chipset_for_pio(drive, 1);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return -1;
 }
 
 /* returns 1 if dma irq issued, 0 otherwise */
@@ -472,11 +456,11 @@
 	unsigned long addr	= siimage_selreg(hwif, 0x1);
 
 	if (SATA_ERROR_REG) {
-		u32 ext_stat = hwif->INL(base + 0x10);
+		u32 ext_stat = readl((void __iomem *)(base + 0x10));
 		u8 watchdog = 0;
 		if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) {
-			u32 sata_error = hwif->INL(SATA_ERROR_REG);
-			hwif->OUTL(sata_error, SATA_ERROR_REG);
+			u32 sata_error = readl((void __iomem *)SATA_ERROR_REG);
+			writel(sata_error, (void __iomem *)SATA_ERROR_REG);
 			watchdog = (sata_error & 0x00680000) ? 1 : 0;
 			printk(KERN_WARNING "%s: sata_error = 0x%08x, "
 				"watchdog = %d, %s\n",
@@ -493,11 +477,11 @@
 	}
 
 	/* return 1 if INTR asserted */
-	if ((hwif->INB(hwif->dma_status) & 0x04) == 0x04)
+	if ((readb((void __iomem *)hwif->dma_status) & 0x04) == 0x04)
 		return 1;
 
 	/* return 1 if Device INTR asserted */
-	if ((hwif->INB(addr) & 8) == 8)
+	if ((readb((void __iomem *)addr) & 8) == 8)
 		return 0;	//return 1;
 
 	return 0;
@@ -519,9 +503,9 @@
 	u32 stat_config		= 0;
 	unsigned long addr	= siimage_selreg(hwif, 0);
 
-	if (hwif->mmio) {
-		stat_config = hwif->INL(addr);
-	} else
+	if (hwif->mmio)
+		stat_config = readl((void __iomem *)addr);
+	else
 		pci_read_config_dword(hwif->pci_dev, addr, &stat_config);
 
 	switch (state) {
@@ -557,9 +541,10 @@
 	if (SATA_STATUS_REG) {
 		ide_hwif_t *hwif	= HWIF(drive);
 
-		if ((hwif->INL(SATA_STATUS_REG) & 0x03) != 0x03) {
+		/* SATA_STATUS_REG is valid only when in MMIO mode */
+		if ((readl((void __iomem *)SATA_STATUS_REG) & 0x03) != 0x03) {
 			printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n",
-				hwif->name, hwif->INL(SATA_STATUS_REG));
+				hwif->name, readl((void __iomem *)SATA_STATUS_REG));
 			HWGROUP(drive)->polling = 0;
 			return ide_started;
 		}
@@ -619,7 +604,8 @@
 	}
 
 	if (SATA_STATUS_REG) {
-		u32 sata_stat = hwif->INL(SATA_STATUS_REG);
+		/* SATA_STATUS_REG is valid only when in MMIO mode */
+		u32 sata_stat = readl((void __iomem *)SATA_STATUS_REG);
 		printk(KERN_WARNING "%s: reset phy, status=0x%08x, %s\n",
 			hwif->name, sata_stat, __FUNCTION__);
 		if (!(sata_stat)) {
@@ -898,7 +884,8 @@
        	base = (unsigned long) addr;
 
 	hwif->dma_base			= base + (ch ? 0x08 : 0x00);
-	hwif->mmio			= 2;
+
+	hwif->mmio = 1;
 }
 
 static int is_dev_seagate_sata(ide_drive_t *drive)
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 1afff65..2ba0669 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -667,68 +667,21 @@
 	return ide_dma_enable(drive);
 }
 
-static int sis5513_config_drive_xfer_rate (ide_drive_t *drive)
+static int sis5513_config_xfer_rate(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
+	config_art_rwp_pio(drive, 5);
 
 	drive->init_speed = 0;
 
-	if (id && (id->capability & 1) && drive->autodma) {
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-		if (ide_use_dma(drive)) {
-			if (config_chipset_for_dma(drive))
-				return hwif->ide_dma_on(drive);
-		}
-
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
+	if (ide_use_fast_pio(drive))
 		sis5513_tune_drive(drive, 5);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return -1;
 }
 
-/* initiates/aborts (U)DMA read/write operations on a drive. */
-static int sis5513_config_xfer_rate (ide_drive_t *drive)
-{
-	config_drive_art_rwp(drive);
-	config_art_rwp_pio(drive, 5);
-	return sis5513_config_drive_xfer_rate(drive);
-}
-
-/*
-  Future simpler config_xfer_rate :
-   When ide_find_best_mode is made bad-drive aware
-   - remove config_drive_xfer_rate and config_chipset_for_dma,
-   - replace config_xfer_rate with the following
-
-static int sis5513_config_xfer_rate (ide_drive_t *drive)
-{
-	u16 w80 = HWIF(drive)->udma_four;
-	u16 speed;
-
-	config_drive_art_rwp(drive);
-	config_art_rwp_pio(drive, 5);
-
-	speed = ide_find_best_mode(drive,
-		XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
-		(chipset_family >= ATA_33 ? XFER_UDMA : 0) |
-		(w80 && chipset_family >= ATA_66 ? XFER_UDMA_66 : 0) |
-		(w80 && chipset_family >= ATA_100a ? XFER_UDMA_100 : 0) |
-		(w80 && chipset_family >= ATA_133a ? XFER_UDMA_133 : 0));
-
-	sis5513_tune_chipset(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);
-}
-*/
-
 /* Chip detection and general config */
 static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name)
 {
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index 170a261..3a8a76f 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -161,14 +161,14 @@
 		if (id->field_valid & 2) {
 			if ((id->dma_mword & hwif->mwdma_mask) ||
 			    (id->dma_1word & hwif->swdma_mask))
-				return hwif->ide_dma_on(drive);
+				return 0;
 		}
 
-		if (__ide_dma_good_drive(drive))
-			return hwif->ide_dma_on(drive);
+		if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150)
+			return 0;
 	} while (0);
 
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 /*
@@ -215,7 +215,7 @@
 	 * Was DMA enabled?  If so, disable it - we're resetting the
 	 * host.  The IDE layer will be handling the drive for us.
 	 */
-	val = hwif->INB(dma_base);
+	val = inb(dma_base);
 	if (val & 1) {
 		outb(val & ~1, dma_base);
 		printk("sl82c105: DMA was enabled\n");
@@ -259,28 +259,22 @@
 {
 	DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name));
 
-	if (config_for_dma(drive)) {
-		config_for_pio(drive, 4, 0, 0);
-		return HWIF(drive)->ide_dma_off_quietly(drive);
-	}
+	if (config_for_dma(drive))
+		return 1;
 	printk(KERN_INFO "%s: DMA enabled\n", drive->name);
 	return __ide_dma_on(drive);
 }
 
-static int sl82c105_ide_dma_off_quietly (ide_drive_t *drive)
+static void sl82c105_dma_off_quietly(ide_drive_t *drive)
 {
 	u8 speed = XFER_PIO_0;
-	int rc;
-	
-	DBG(("sl82c105_ide_dma_off_quietly(drive:%s)\n", drive->name));
 
-	rc = __ide_dma_off_quietly(drive);
+	DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name));
+
+	ide_dma_off_quietly(drive);
 	if (drive->pio_speed)
 		speed = drive->pio_speed - XFER_PIO_0;
 	config_for_pio(drive, speed, 0, 1);
-	drive->current_speed = drive->pio_speed;
-
-	return rc;
 }
 
 /*
@@ -401,11 +395,9 @@
 /*
  * Initialise the chip
  */
-
 static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
 {
 	unsigned int rev;
-	u8 dma_state;
 
 	DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index));
 
@@ -431,7 +423,6 @@
 	if (!hwif->dma_base)
 		return;
 
-	dma_state = hwif->INB(hwif->dma_base + 2) & ~0x60;
 	rev = sl82c105_bridge_revision(hwif->pci_dev);
 	if (rev <= 5) {
 		/*
@@ -441,15 +432,12 @@
 		printk("    %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
 		       hwif->name, rev);
 	} else {
-		dma_state |= 0x60;
-
 		hwif->atapi_dma = 1;
-		hwif->mwdma_mask = 0x07;
-		hwif->swdma_mask = 0x07;
+		hwif->mwdma_mask = 0x04;
 
 		hwif->ide_dma_check = &sl82c105_check_drive;
 		hwif->ide_dma_on = &sl82c105_ide_dma_on;
-		hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly;
+		hwif->dma_off_quietly = &sl82c105_dma_off_quietly;
 		hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq;
 		hwif->dma_start = &sl82c105_ide_dma_start;
 		hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;
@@ -462,7 +450,6 @@
 		if (hwif->mate)
 			hwif->serialized = hwif->mate->serialized = 1;
 	}
-	hwif->OUTB(dma_state, hwif->dma_base + 2);
 }
 
 static ide_pci_device_t sl82c105_chipset __devinitdata = {
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
index 2663ddb..ae7eb58 100644
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -179,26 +179,16 @@
 
 static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
-
 	drive->init_speed = 0;
 
-	if ((id->capability & 1) && drive->autodma) {
+	if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive))
+		return 0;
 
-		if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive))
-			return hwif->ide_dma_on(drive);
+	if (ide_use_fast_pio(drive))
+		(void)slc90e66_tune_chipset(drive, XFER_PIO_0 +
+				ide_get_best_pio_mode(drive, 255, 4, NULL));
 
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
-		(void) hwif->speedproc(drive, XFER_PIO_0 +
-				       ide_get_best_pio_mode(drive, 255, 4, NULL));
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+	return -1;
 }
 
 static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c
index 2ad72bb..0b6d81d 100644
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -45,7 +45,7 @@
 
 	scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f;
 	scr |= mode;
-	hwif->OUTW(scr, scr_port);
+	outw(scr, scr_port);
 
 	return ide_config_drive_speed(drive, speed);
 }
@@ -89,15 +89,15 @@
 		       "attempting recovery...\n", drive->name);
 
 		/* Stop DMA */
-		hwif->OUTB(dma_cmd & ~0x01, hwif->dma_command);
+		outb(dma_cmd & ~0x01, hwif->dma_command);
 
 		/* Setup the dummy DMA transfer */
-		hwif->OUTW(0, sc_base + 0x0a);	/* Sector Count */
-		hwif->OUTW(0, twcr_port);	/* Transfer Word Count 1 or 2 */
+		outw(0, sc_base + 0x0a);	/* Sector Count */
+		outw(0, twcr_port);	/* Transfer Word Count 1 or 2 */
 
 		/* Start the dummy DMA transfer */
-		hwif->OUTB(0x00, hwif->dma_command); /* clear R_OR_WCTR for write */
-		hwif->OUTB(0x01, hwif->dma_command); /* set START_STOPBM */
+		outb(0x00, hwif->dma_command); /* clear R_OR_WCTR for write */
+		outb(0x01, hwif->dma_command); /* set START_STOPBM */
 
 		/*
 		 * If an interrupt was pending, it should come thru shortly.
@@ -128,8 +128,8 @@
 	 * the appropriate system control registers for DMA to work
 	 * with LBA48 and ATAPI devices...
 	 */
-	hwif->OUTW(nsectors, sc_base + 0x0a);	/* Sector Count */
-	hwif->OUTW(SECTOR_SIZE / 2, twcr_port); /* Transfer Word Count 1/2 */
+	outw(nsectors, sc_base + 0x0a);	/* Sector Count */
+	outw(SECTOR_SIZE / 2, twcr_port); /* Transfer Word Count 1/2 */
 
 	/* Install our timeout expiry hook, saving the current handler... */
 	ide_set_hwifdata(hwif, hwgroup->expiry);
@@ -168,7 +168,7 @@
 	}
 
 	/* System Control 1 Register bit 11 (ATA Hard Reset) write */
-	hwif->OUTW(scr1, sc_base + 0x00);
+	outw(scr1, sc_base + 0x00);
 	return 0;
 }
 
@@ -185,23 +185,13 @@
 
 static int tc86c001_config_drive_xfer_rate(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
+	if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+		return 0;
 
-	if ((id->capability & 1) && drive->autodma) {
-
-		if (ide_use_dma(drive) && config_chipset_for_dma(drive))
-			return hwif->ide_dma_on(drive);
-
-		goto fast_ata_pio;
-
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
+	if (ide_use_fast_pio(drive))
 		tc86c001_tune_drive(drive, 255);
-		return hwif->ide_dma_off_quietly(drive);
-	}
-	/* IORDY not supported */
-	return 0;
+
+	return -1;
 }
 
 static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
@@ -210,13 +200,13 @@
 	u16 scr1		= hwif->INW(sc_base + 0x00);;
 
 	/* System Control 1 Register bit 15 (Soft Reset) set */
-	hwif->OUTW(scr1 |  0x8000, sc_base + 0x00);
+	outw(scr1 |  0x8000, sc_base + 0x00);
 
 	/* System Control 1 Register bit 14 (FIFO Reset) set */
-	hwif->OUTW(scr1 |  0x4000, sc_base + 0x00);
+	outw(scr1 |  0x4000, sc_base + 0x00);
 
 	/* System Control 1 Register: reset clear */
-	hwif->OUTW(scr1 & ~0xc000, sc_base + 0x00);
+	outw(scr1 & ~0xc000, sc_base + 0x00);
 
 	/* Store the system control register base for convenience... */
 	hwif->config_data = sc_base;
@@ -234,7 +224,7 @@
 	 * Sector Count Control Register bits 0 and 1 set:
 	 * software sets Sector Count Register for master and slave device
 	 */
-	hwif->OUTW(0x0003, sc_base + 0x0c);
+	outw(0x0003, sc_base + 0x0c);
 
 	/* Sector Count Register limit */
 	hwif->rqsize	 = 0xffff;
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
index b13cce1..5e06179 100644
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -104,29 +104,21 @@
 {
 	int speed = ide_dma_speed(drive, 0); /* No ultra speeds */
 
-	if (!speed) { 
-		u8 pspeed = ide_get_best_pio_mode(drive, 255, 4, NULL);
-		speed = XFER_PIO_0 + pspeed;
-	}
-	
+	if (!speed)
+		return 0;
+
 	(void) triflex_tune_chipset(drive, speed);
 	 return ide_dma_enable(drive);
 }
 
 static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct hd_driveid *id	= drive->id;
+	if (ide_use_dma(drive) && triflex_config_drive_for_dma(drive))
+		return 0;
 
-	if ((id->capability & 1) && drive->autodma) {
-		if (ide_use_dma(drive)) {
-			if (triflex_config_drive_for_dma(drive))
-				return hwif->ide_dma_on(drive);
-		}
-	}
+	triflex_tune_drive(drive, 255);
 
-	hwif->tuneproc(drive, 255);
-	return hwif->ide_dma_off_quietly(drive);
+	return -1;
 }
 
 static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
index 174b88c..cbb1b11 100644
--- a/drivers/ide/pci/trm290.c
+++ b/drivers/ide/pci/trm290.c
@@ -157,16 +157,16 @@
 	if (reg != hwif->select_data) {
 		hwif->select_data = reg;
 		/* set PIO/DMA */
-		hwif->OUTB(0x51|(hwif->channel<<3), hwif->config_data+1);
-		hwif->OUTW(reg & 0xff, hwif->config_data);
+		outb(0x51 | (hwif->channel << 3), hwif->config_data + 1);
+		outw(reg & 0xff, hwif->config_data);
 	}
 
 	/* enable IRQ if not probing */
 	if (drive->present) {
-		reg = hwif->INW(hwif->config_data + 3);
+		reg = inw(hwif->config_data + 3);
 		reg &= 0x13;
 		reg &= ~(1 << hwif->channel);
-		hwif->OUTW(reg, hwif->config_data+3);
+		outw(reg, hwif->config_data + 3);
 	}
 
 	local_irq_restore(flags);
@@ -177,15 +177,12 @@
 	trm290_prepare_drive(drive, drive->using_dma);
 }
 
-#ifdef CONFIG_BLK_DEV_IDEDMA
 static void trm290_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-
 	BUG_ON(HWGROUP(drive)->handler != NULL);	/* paranoia check */
 	ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
 	/* issue cmd to drive */
-	hwif->OUTB(command, IDE_COMMAND_REG);
+	outb(command, IDE_COMMAND_REG);
 }
 
 static int trm290_ide_dma_setup(ide_drive_t *drive)
@@ -211,10 +208,10 @@
 	}
 	/* select DMA xfer */
 	trm290_prepare_drive(drive, 1);
-	hwif->OUTL(hwif->dmatable_dma|rw, hwif->dma_command);
+	outl(hwif->dmatable_dma | rw, hwif->dma_command);
 	drive->waiting_for_dma = 1;
 	/* start DMA */
-	hwif->OUTW((count * 2) - 1, hwif->dma_status);
+	outw((count * 2) - 1, hwif->dma_status);
 	return 0;
 }
 
@@ -230,7 +227,7 @@
 	drive->waiting_for_dma = 0;
 	/* purge DMA mappings */
 	ide_destroy_dmatable(drive);
-	status = hwif->INW(hwif->dma_status);
+	status = inw(hwif->dma_status);
 	return (status != 0x00ff);
 }
 
@@ -239,10 +236,9 @@
 	ide_hwif_t *hwif = HWIF(drive);
 	u16 status = 0;
 
-	status = hwif->INW(hwif->dma_status);
+	status = inw(hwif->dma_status);
 	return (status == 0x00ff);
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
 
 /*
  * Invoked from ide-dma.c at boot time.
@@ -269,15 +265,15 @@
 
 	local_irq_save(flags);
 	/* put config reg into first byte of hwif->select_data */
-	hwif->OUTB(0x51|(hwif->channel<<3), hwif->config_data+1);
+	outb(0x51 | (hwif->channel << 3), hwif->config_data + 1);
 	/* select PIO as default */
 	hwif->select_data = 0x21;
-	hwif->OUTB(hwif->select_data, hwif->config_data);
+	outb(hwif->select_data, hwif->config_data);
 	/* get IRQ info */
-	reg = hwif->INB(hwif->config_data+3);
+	reg = inb(hwif->config_data + 3);
 	/* mask IRQs for both ports */
 	reg = (reg & 0x10) | 0x03;
-	hwif->OUTB(reg, hwif->config_data+3);
+	outb(reg, hwif->config_data + 3);
 	local_irq_restore(flags);
 
 	if ((reg & 0x10))
@@ -289,13 +285,11 @@
 
 	ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3);
 
-#ifdef CONFIG_BLK_DEV_IDEDMA
 	hwif->dma_setup = &trm290_ide_dma_setup;
 	hwif->dma_exec_cmd = &trm290_ide_dma_exec_cmd;
 	hwif->dma_start = &trm290_ide_dma_start;
 	hwif->ide_dma_end = &trm290_ide_dma_end;
 	hwif->ide_dma_test_irq = &trm290_ide_dma_test_irq;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
 
 	hwif->selectproc = &trm290_selectproc;
 	hwif->autodma = 0;		/* play it safe for now */
@@ -312,16 +306,16 @@
 		static u16 next_offset = 0;
 		u8 old_mask;
 
-		hwif->OUTB(0x54|(hwif->channel<<3), hwif->config_data+1);
-		old = hwif->INW(hwif->config_data);
+		outb(0x54 | (hwif->channel << 3), hwif->config_data + 1);
+		old = inw(hwif->config_data);
 		old &= ~1;
-		old_mask = hwif->INB(old+2);
+		old_mask = inb(old + 2);
 		if (old != compat && old_mask == 0xff) {
 			/* leave lower 10 bits untouched */
 			compat += (next_offset += 0x400);
 			hwif->io_ports[IDE_CONTROL_OFFSET] = compat + 2;
-			hwif->OUTW(compat|1, hwif->config_data);
-			new = hwif->INW(hwif->config_data);
+			outw(compat | 1, hwif->config_data);
+			new = inw(hwif->config_data);
 			printk(KERN_INFO "%s: control basereg workaround: "
 				"old=0x%04x, new=0x%04x\n",
 				hwif->name, old, new & ~1);
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 6fb6e50..a508550 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -240,8 +240,9 @@
 	via_set_drive(drive, speed);
 
 	if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
-		return hwif->ide_dma_on(drive);
-	return hwif->ide_dma_off_quietly(drive);
+		return 0;
+
+	return -1;
 }
 
 static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index d8ea237..395d352 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1237,7 +1237,7 @@
        	hwif->OUTBSYNC = pmac_outbsync;
 
 	/* Tell common code _not_ to mess with resources */
-	hwif->mmio = 2;
+	hwif->mmio = 1;
 	hwif->hwif_data = pmif;
 	pmac_ide_init_hwif_ports(&hwif->hw, pmif->regbase, 0, &hwif->irq);
 	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
@@ -1979,16 +1979,12 @@
 	return 1;
 }
 
-static int
-pmac_ide_dma_host_off (ide_drive_t *drive)
+static void pmac_ide_dma_host_off(ide_drive_t *drive)
 {
-	return 0;
 }
 
-static int
-pmac_ide_dma_host_on (ide_drive_t *drive)
+static int pmac_ide_dma_host_on(ide_drive_t *drive)
 {
-	return 0;
 }
 
 static int
@@ -2034,7 +2030,7 @@
 		return;
 	}
 
-	hwif->ide_dma_off_quietly = &__ide_dma_off_quietly;
+	hwif->dma_off_quietly = &ide_dma_off_quietly;
 	hwif->ide_dma_on = &__ide_dma_on;
 	hwif->ide_dma_check = &pmac_ide_dma_check;
 	hwif->dma_setup = &pmac_ide_dma_setup;
@@ -2042,8 +2038,8 @@
 	hwif->dma_start = &pmac_ide_dma_start;
 	hwif->ide_dma_end = &pmac_ide_dma_end;
 	hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
-	hwif->ide_dma_host_off = &pmac_ide_dma_host_off;
-	hwif->ide_dma_host_on = &pmac_ide_dma_host_on;
+	hwif->dma_host_off = &pmac_ide_dma_host_off;
+	hwif->dma_host_on = &pmac_ide_dma_host_on;
 	hwif->ide_dma_timeout = &__ide_dma_timeout;
 	hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq;
 
diff --git a/drivers/ide/ppc/scc_pata.c b/drivers/ide/ppc/scc_pata.c
new file mode 100644
index 0000000..de64b02
--- /dev/null
+++ b/drivers/ide/ppc/scc_pata.c
@@ -0,0 +1,831 @@
+/*
+ * Support for IDE interfaces on Celleb platform
+ *
+ * (C) Copyright 2006 TOSHIBA CORPORATION
+ *
+ * This code is based on drivers/ide/pci/siimage.c:
+ * Copyright (C) 2001-2002	Andre Hedrick <andre@linux-ide.org>
+ * Copyright (C) 2003		Red Hat <alan@redhat.com>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+
+#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA            0x01b4
+
+#define SCC_PATA_NAME           "scc IDE"
+
+#define TDVHSEL_MASTER          0x00000001
+#define TDVHSEL_SLAVE           0x00000004
+
+#define MODE_JCUSFEN            0x00000080
+
+#define CCKCTRL_ATARESET        0x00040000
+#define CCKCTRL_BUFCNT          0x00020000
+#define CCKCTRL_CRST            0x00010000
+#define CCKCTRL_OCLKEN          0x00000100
+#define CCKCTRL_ATACLKOEN       0x00000002
+#define CCKCTRL_LCLKEN          0x00000001
+
+#define QCHCD_IOS_SS		0x00000001
+
+#define QCHSD_STPDIAG		0x00020000
+
+#define INTMASK_MSK             0xD1000012
+#define INTSTS_SERROR		0x80000000
+#define INTSTS_PRERR		0x40000000
+#define INTSTS_RERR		0x10000000
+#define INTSTS_ICERR		0x01000000
+#define INTSTS_BMSINT		0x00000010
+#define INTSTS_BMHE		0x00000008
+#define INTSTS_IOIRQS           0x00000004
+#define INTSTS_INTRQ            0x00000002
+#define INTSTS_ACTEINT          0x00000001
+
+#define ECMODE_VALUE 0x01
+
+static struct scc_ports {
+	unsigned long ctl, dma;
+	unsigned char hwif_id;  /* for removing hwif from system */
+} scc_ports[MAX_HWIFS];
+
+/* PIO transfer mode  table */
+/* JCHST */
+static unsigned long JCHSTtbl[2][7] = {
+	{0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00},   /* 100MHz */
+	{0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00}    /* 133MHz */
+};
+
+/* JCHHT */
+static unsigned long JCHHTtbl[2][7] = {
+	{0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00},   /* 100MHz */
+	{0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00}    /* 133MHz */
+};
+
+/* JCHCT */
+static unsigned long JCHCTtbl[2][7] = {
+	{0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00},   /* 100MHz */
+	{0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00}    /* 133MHz */
+};
+
+
+/* DMA transfer mode  table */
+/* JCHDCTM/JCHDCTS */
+static unsigned long JCHDCTxtbl[2][7] = {
+	{0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00},   /* 100MHz */
+	{0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00}    /* 133MHz */
+};
+
+/* JCSTWTM/JCSTWTS  */
+static unsigned long JCSTWTxtbl[2][7] = {
+	{0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00},   /* 100MHz */
+	{0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02}    /* 133MHz */
+};
+
+/* JCTSS */
+static unsigned long JCTSStbl[2][7] = {
+	{0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00},   /* 100MHz */
+	{0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05}    /* 133MHz */
+};
+
+/* JCENVT */
+static unsigned long JCENVTtbl[2][7] = {
+	{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00},   /* 100MHz */
+	{0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}    /* 133MHz */
+};
+
+/* JCACTSELS/JCACTSELM */
+static unsigned long JCACTSELtbl[2][7] = {
+	{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00},   /* 100MHz */
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}    /* 133MHz */
+};
+
+
+static u8 scc_ide_inb(unsigned long port)
+{
+	u32 data = in_be32((void*)port);
+	return (u8)data;
+}
+
+static u16 scc_ide_inw(unsigned long port)
+{
+	u32 data = in_be32((void*)port);
+	return (u16)data;
+}
+
+static void scc_ide_insw(unsigned long port, void *addr, u32 count)
+{
+	u16 *ptr = (u16 *)addr;
+	while (count--) {
+		*ptr++ = le16_to_cpu(in_be32((void*)port));
+	}
+}
+
+static void scc_ide_insl(unsigned long port, void *addr, u32 count)
+{
+	u16 *ptr = (u16 *)addr;
+	while (count--) {
+		*ptr++ = le16_to_cpu(in_be32((void*)port));
+		*ptr++ = le16_to_cpu(in_be32((void*)port));
+	}
+}
+
+static void scc_ide_outb(u8 addr, unsigned long port)
+{
+	out_be32((void*)port, addr);
+}
+
+static void scc_ide_outw(u16 addr, unsigned long port)
+{
+	out_be32((void*)port, addr);
+}
+
+static void
+scc_ide_outbsync(ide_drive_t * drive, u8 addr, unsigned long port)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+
+	out_be32((void*)port, addr);
+	__asm__ __volatile__("eieio":::"memory");
+	in_be32((void*)(hwif->dma_base + 0x01c));
+	__asm__ __volatile__("eieio":::"memory");
+}
+
+static void
+scc_ide_outsw(unsigned long port, void *addr, u32 count)
+{
+	u16 *ptr = (u16 *)addr;
+	while (count--) {
+		out_be32((void*)port, cpu_to_le16(*ptr++));
+	}
+}
+
+static void
+scc_ide_outsl(unsigned long port, void *addr, u32 count)
+{
+	u16 *ptr = (u16 *)addr;
+	while (count--) {
+		out_be32((void*)port, cpu_to_le16(*ptr++));
+		out_be32((void*)port, cpu_to_le16(*ptr++));
+	}
+}
+
+/**
+ *	scc_ratemask	-	Compute available modes
+ *	@drive: IDE drive
+ *
+ *	Compute the available speeds for the devices on the interface.
+ *	Enforce UDMA33 as a limit if there is no 80pin cable present.
+ */
+
+static u8 scc_ratemask(ide_drive_t *drive)
+{
+	u8 mode = 4;
+
+	if (!eighty_ninty_three(drive))
+		mode = min(mode, (u8)1);
+	return mode;
+}
+
+/**
+ *	scc_tuneproc	-	tune a drive PIO mode
+ *	@drive: drive to tune
+ *	@mode_wanted: the target operating mode
+ *
+ *	Load the timing settings for this device mode into the
+ *	controller.
+ */
+
+static void scc_tuneproc(ide_drive_t *drive, byte mode_wanted)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+	struct scc_ports *ports = ide_get_hwifdata(hwif);
+	unsigned long ctl_base = ports->ctl;
+	unsigned long cckctrl_port = ctl_base + 0xff0;
+	unsigned long piosht_port = ctl_base + 0x000;
+	unsigned long pioct_port = ctl_base + 0x004;
+	unsigned long reg;
+	unsigned char speed = XFER_PIO_0;
+	int offset;
+
+	mode_wanted = ide_get_best_pio_mode(drive, mode_wanted, 4, NULL);
+	switch (mode_wanted) {
+	case 4:
+		speed = XFER_PIO_4;
+		break;
+	case 3:
+		speed = XFER_PIO_3;
+		break;
+	case 2:
+		speed = XFER_PIO_2;
+		break;
+	case 1:
+		speed = XFER_PIO_1;
+		break;
+	case 0:
+	default:
+		speed = XFER_PIO_0;
+		break;
+	}
+
+	reg = in_be32((void __iomem *)cckctrl_port);
+	if (reg & CCKCTRL_ATACLKOEN) {
+		offset = 1; /* 133MHz */
+	} else {
+		offset = 0; /* 100MHz */
+	}
+	reg = JCHSTtbl[offset][mode_wanted] << 16 | JCHHTtbl[offset][mode_wanted];
+	out_be32((void __iomem *)piosht_port, reg);
+	reg = JCHCTtbl[offset][mode_wanted];
+	out_be32((void __iomem *)pioct_port, reg);
+
+	ide_config_drive_speed(drive, speed);
+}
+
+/**
+ *	scc_tune_chipset	-	tune a drive DMA mode
+ *	@drive: Drive to set up
+ *	@xferspeed: speed we want to achieve
+ *
+ *	Load the timing settings for this device mode into the
+ *	controller.
+ */
+
+static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+	u8 speed = ide_rate_filter(scc_ratemask(drive), xferspeed);
+	struct scc_ports *ports = ide_get_hwifdata(hwif);
+	unsigned long ctl_base = ports->ctl;
+	unsigned long cckctrl_port = ctl_base + 0xff0;
+	unsigned long mdmact_port = ctl_base + 0x008;
+	unsigned long mcrcst_port = ctl_base + 0x00c;
+	unsigned long sdmact_port = ctl_base + 0x010;
+	unsigned long scrcst_port = ctl_base + 0x014;
+	unsigned long udenvt_port = ctl_base + 0x018;
+	unsigned long tdvhsel_port   = ctl_base + 0x020;
+	int is_slave = (&hwif->drives[1] == drive);
+	int offset, idx;
+	unsigned long reg;
+	unsigned long jcactsel;
+
+	reg = in_be32((void __iomem *)cckctrl_port);
+	if (reg & CCKCTRL_ATACLKOEN) {
+		offset = 1; /* 133MHz */
+	} else {
+		offset = 0; /* 100MHz */
+	}
+
+	switch (speed) {
+	case XFER_UDMA_6:
+		idx = 6;
+		break;
+	case XFER_UDMA_5:
+		idx = 5;
+		break;
+	case XFER_UDMA_4:
+		idx = 4;
+		break;
+	case XFER_UDMA_3:
+		idx = 3;
+		break;
+	case XFER_UDMA_2:
+		idx = 2;
+		break;
+	case XFER_UDMA_1:
+		idx = 1;
+		break;
+	case XFER_UDMA_0:
+		idx = 0;
+		break;
+	default:
+		return 1;
+	}
+
+	jcactsel = JCACTSELtbl[offset][idx];
+	if (is_slave) {
+		out_be32((void __iomem *)sdmact_port, JCHDCTxtbl[offset][idx]);
+		out_be32((void __iomem *)scrcst_port, JCSTWTxtbl[offset][idx]);
+		jcactsel = jcactsel << 2;
+		out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_SLAVE) | jcactsel);
+	} else {
+		out_be32((void __iomem *)mdmact_port, JCHDCTxtbl[offset][idx]);
+		out_be32((void __iomem *)mcrcst_port, JCSTWTxtbl[offset][idx]);
+		out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_MASTER) | jcactsel);
+	}
+	reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx];
+	out_be32((void __iomem *)udenvt_port, reg);
+
+	return ide_config_drive_speed(drive, speed);
+}
+
+/**
+ *	scc_config_chipset_for_dma	-	configure for DMA
+ *	@drive: drive to configure
+ *
+ *	Called by scc_config_drive_for_dma().
+ */
+
+static int scc_config_chipset_for_dma(ide_drive_t *drive)
+{
+	u8 speed = ide_dma_speed(drive, scc_ratemask(drive));
+
+	if (!speed)
+		return 0;
+
+	if (scc_tune_chipset(drive, speed))
+		return 0;
+
+	return ide_dma_enable(drive);
+}
+
+/**
+ *	scc_configure_drive_for_dma	-	set up for DMA transfers
+ *	@drive: drive we are going to set up
+ *
+ *	Set up the drive for DMA, tune the controller and drive as
+ *	required.
+ *      If the drive isn't suitable for DMA or we hit other problems
+ *      then we will drop down to PIO and set up PIO appropriately.
+ *      (return 1)
+ */
+
+static int scc_config_drive_for_dma(ide_drive_t *drive)
+{
+	if (ide_use_dma(drive) && scc_config_chipset_for_dma(drive))
+		return 0;
+
+	if (ide_use_fast_pio(drive))
+		scc_tuneproc(drive, 4);
+
+	return -1;
+}
+
+/**
+ *	scc_ide_dma_setup	-	begin a DMA phase
+ *	@drive: target device
+ *
+ *	Build an IDE DMA PRD (IDE speak for scatter gather table)
+ *	and then set up the DMA transfer registers.
+ *
+ *	Returns 0 on success. If a PIO fallback is required then 1
+ *	is returned.
+ */
+
+static int scc_dma_setup(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct request *rq = HWGROUP(drive)->rq;
+	unsigned int reading;
+	u8 dma_stat;
+
+	if (rq_data_dir(rq))
+		reading = 0;
+	else
+		reading = 1 << 3;
+
+	/* fall back to pio! */
+	if (!ide_build_dmatable(drive, rq)) {
+		ide_map_sg(drive, rq);
+		return 1;
+	}
+
+	/* PRD table */
+	out_be32((void __iomem *)hwif->dma_prdtable, hwif->dmatable_dma);
+
+	/* specify r/w */
+	out_be32((void __iomem *)hwif->dma_command, reading);
+
+	/* read dma_status for INTR & ERROR flags */
+	dma_stat = in_be32((void __iomem *)hwif->dma_status);
+
+	/* clear INTR & ERROR flags */
+	out_be32((void __iomem *)hwif->dma_status, dma_stat|6);
+	drive->waiting_for_dma = 1;
+	return 0;
+}
+
+
+/**
+ *	scc_ide_dma_end	-	Stop DMA
+ *	@drive: IDE drive
+ *
+ *	Check and clear INT Status register.
+ *      Then call __ide_dma_end().
+ */
+
+static int scc_ide_dma_end(ide_drive_t * drive)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+	unsigned long intsts_port = hwif->dma_base + 0x014;
+	u32 reg;
+
+	while (1) {
+		reg = in_be32((void __iomem *)intsts_port);
+
+		if (reg & INTSTS_SERROR) {
+			printk(KERN_WARNING "%s: SERROR\n", SCC_PATA_NAME);
+			out_be32((void __iomem *)intsts_port, INTSTS_SERROR|INTSTS_BMSINT);
+
+			out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
+			continue;
+		}
+
+		if (reg & INTSTS_PRERR) {
+			u32 maea0, maec0;
+			unsigned long ctl_base = hwif->config_data;
+
+			maea0 = in_be32((void __iomem *)(ctl_base + 0xF50));
+			maec0 = in_be32((void __iomem *)(ctl_base + 0xF54));
+
+			printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", SCC_PATA_NAME, maea0, maec0);
+
+			out_be32((void __iomem *)intsts_port, INTSTS_PRERR|INTSTS_BMSINT);
+
+			out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
+			continue;
+		}
+
+		if (reg & INTSTS_RERR) {
+			printk(KERN_WARNING "%s: Response Error\n", SCC_PATA_NAME);
+			out_be32((void __iomem *)intsts_port, INTSTS_RERR|INTSTS_BMSINT);
+
+			out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
+			continue;
+		}
+
+		if (reg & INTSTS_ICERR) {
+			out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
+
+			printk(KERN_WARNING "%s: Illegal Configuration\n", SCC_PATA_NAME);
+			out_be32((void __iomem *)intsts_port, INTSTS_ICERR|INTSTS_BMSINT);
+			continue;
+		}
+
+		if (reg & INTSTS_BMSINT) {
+			printk(KERN_WARNING "%s: Internal Bus Error\n", SCC_PATA_NAME);
+			out_be32((void __iomem *)intsts_port, INTSTS_BMSINT);
+
+			ide_do_reset(drive);
+			continue;
+		}
+
+		if (reg & INTSTS_BMHE) {
+			out_be32((void __iomem *)intsts_port, INTSTS_BMHE);
+			continue;
+		}
+
+		if (reg & INTSTS_ACTEINT) {
+			out_be32((void __iomem *)intsts_port, INTSTS_ACTEINT);
+			continue;
+		}
+
+		if (reg & INTSTS_IOIRQS) {
+			out_be32((void __iomem *)intsts_port, INTSTS_IOIRQS);
+			continue;
+		}
+		break;
+	}
+
+	return __ide_dma_end(drive);
+}
+
+/**
+ *	setup_mmio_scc	-	map CTRL/BMID region
+ *	@dev: PCI device we are configuring
+ *	@name: device name
+ *
+ */
+
+static int setup_mmio_scc (struct pci_dev *dev, const char *name)
+{
+	unsigned long ctl_base = pci_resource_start(dev, 0);
+	unsigned long dma_base = pci_resource_start(dev, 1);
+	unsigned long ctl_size = pci_resource_len(dev, 0);
+	unsigned long dma_size = pci_resource_len(dev, 1);
+	void *ctl_addr;
+	void *dma_addr;
+	int i;
+
+	for (i = 0; i < MAX_HWIFS; i++) {
+		if (scc_ports[i].ctl == 0)
+			break;
+	}
+	if (i >= MAX_HWIFS)
+		return -ENOMEM;
+
+	if (!request_mem_region(ctl_base, ctl_size, name)) {
+		printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME);
+		goto fail_0;
+	}
+
+	if (!request_mem_region(dma_base, dma_size, name)) {
+		printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME);
+		goto fail_1;
+	}
+
+	if ((ctl_addr = ioremap(ctl_base, ctl_size)) == NULL)
+		goto fail_2;
+
+	if ((dma_addr = ioremap(dma_base, dma_size)) == NULL)
+		goto fail_3;
+
+	pci_set_master(dev);
+	scc_ports[i].ctl = (unsigned long)ctl_addr;
+	scc_ports[i].dma = (unsigned long)dma_addr;
+	pci_set_drvdata(dev, (void *) &scc_ports[i]);
+
+	return 1;
+
+ fail_3:
+	iounmap(ctl_addr);
+ fail_2:
+	release_mem_region(dma_base, dma_size);
+ fail_1:
+	release_mem_region(ctl_base, ctl_size);
+ fail_0:
+	return -ENOMEM;
+}
+
+/**
+ *	init_setup_scc	-	set up an SCC PATA Controller
+ *	@dev: PCI device
+ *	@d: IDE PCI device
+ *
+ *	Perform the initial set up for this device.
+ */
+
+static int __devinit init_setup_scc(struct pci_dev *dev, ide_pci_device_t *d)
+{
+	unsigned long ctl_base;
+	unsigned long dma_base;
+	unsigned long cckctrl_port;
+	unsigned long intmask_port;
+	unsigned long mode_port;
+	unsigned long ecmode_port;
+	unsigned long dma_status_port;
+	u32 reg = 0;
+	struct scc_ports *ports;
+	int rc;
+
+	rc = setup_mmio_scc(dev, d->name);
+	if (rc < 0) {
+		return rc;
+	}
+
+	ports = pci_get_drvdata(dev);
+	ctl_base = ports->ctl;
+	dma_base = ports->dma;
+	cckctrl_port = ctl_base + 0xff0;
+	intmask_port = dma_base + 0x010;
+	mode_port = ctl_base + 0x024;
+	ecmode_port = ctl_base + 0xf00;
+	dma_status_port = dma_base + 0x004;
+
+	/* controller initialization */
+	reg = 0;
+	out_be32((void*)cckctrl_port, reg);
+	reg |= CCKCTRL_ATACLKOEN;
+	out_be32((void*)cckctrl_port, reg);
+	reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN;
+	out_be32((void*)cckctrl_port, reg);
+	reg |= CCKCTRL_CRST;
+	out_be32((void*)cckctrl_port, reg);
+
+	for (;;) {
+		reg = in_be32((void*)cckctrl_port);
+		if (reg & CCKCTRL_CRST)
+			break;
+		udelay(5000);
+	}
+
+	reg |= CCKCTRL_ATARESET;
+	out_be32((void*)cckctrl_port, reg);
+
+	out_be32((void*)ecmode_port, ECMODE_VALUE);
+	out_be32((void*)mode_port, MODE_JCUSFEN);
+	out_be32((void*)intmask_port, INTMASK_MSK);
+
+	return ide_setup_pci_device(dev, d);
+}
+
+/**
+ *	init_mmio_iops_scc	-	set up the iops for MMIO
+ *	@hwif: interface to set up
+ *
+ */
+
+static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif)
+{
+	struct pci_dev *dev = hwif->pci_dev;
+	struct scc_ports *ports = pci_get_drvdata(dev);
+	unsigned long dma_base = ports->dma;
+
+	ide_set_hwifdata(hwif, ports);
+
+	hwif->INB = scc_ide_inb;
+	hwif->INW = scc_ide_inw;
+	hwif->INSW = scc_ide_insw;
+	hwif->INSL = scc_ide_insl;
+	hwif->OUTB = scc_ide_outb;
+	hwif->OUTBSYNC = scc_ide_outbsync;
+	hwif->OUTW = scc_ide_outw;
+	hwif->OUTSW = scc_ide_outsw;
+	hwif->OUTSL = scc_ide_outsl;
+
+	hwif->io_ports[IDE_DATA_OFFSET] = dma_base + 0x20;
+	hwif->io_ports[IDE_ERROR_OFFSET] = dma_base + 0x24;
+	hwif->io_ports[IDE_NSECTOR_OFFSET] = dma_base + 0x28;
+	hwif->io_ports[IDE_SECTOR_OFFSET] = dma_base + 0x2c;
+	hwif->io_ports[IDE_LCYL_OFFSET] = dma_base + 0x30;
+	hwif->io_ports[IDE_HCYL_OFFSET] = dma_base + 0x34;
+	hwif->io_ports[IDE_SELECT_OFFSET] = dma_base + 0x38;
+	hwif->io_ports[IDE_STATUS_OFFSET] = dma_base + 0x3c;
+	hwif->io_ports[IDE_CONTROL_OFFSET] = dma_base + 0x40;
+
+	hwif->irq = hwif->pci_dev->irq;
+	hwif->dma_base = dma_base;
+	hwif->config_data = ports->ctl;
+	hwif->mmio = 1;
+}
+
+/**
+ *	init_iops_scc	-	set up iops
+ *	@hwif: interface to set up
+ *
+ *	Do the basic setup for the SCC hardware interface
+ *	and then do the MMIO setup.
+ */
+
+static void __devinit init_iops_scc(ide_hwif_t *hwif)
+{
+	struct pci_dev *dev =  hwif->pci_dev;
+	hwif->hwif_data = NULL;
+	if (pci_get_drvdata(dev) == NULL)
+		return;
+	init_mmio_iops_scc(hwif);
+}
+
+/**
+ *	init_hwif_scc	-	set up hwif
+ *	@hwif: interface to set up
+ *
+ *	We do the basic set up of the interface structure. The SCC
+ *	requires several custom handlers so we override the default
+ *	ide DMA handlers appropriately.
+ */
+
+static void __devinit init_hwif_scc(ide_hwif_t *hwif)
+{
+	struct scc_ports *ports = ide_get_hwifdata(hwif);
+
+	ports->hwif_id = hwif->index;
+
+	hwif->dma_command = hwif->dma_base;
+	hwif->dma_status = hwif->dma_base + 0x04;
+	hwif->dma_prdtable = hwif->dma_base + 0x08;
+
+	/* PTERADD */
+	out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma);
+
+	hwif->dma_setup = scc_dma_setup;
+	hwif->ide_dma_end = scc_ide_dma_end;
+	hwif->speedproc = scc_tune_chipset;
+	hwif->tuneproc = scc_tuneproc;
+	hwif->ide_dma_check = scc_config_drive_for_dma;
+
+	hwif->drives[0].autotune = IDE_TUNE_AUTO;
+	hwif->drives[1].autotune = IDE_TUNE_AUTO;
+
+	if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN) {
+		hwif->ultra_mask = 0x7f; /* 133MHz */
+	} else {
+		hwif->ultra_mask = 0x3f; /* 100MHz */
+	}
+	hwif->mwdma_mask = 0x00;
+	hwif->swdma_mask = 0x00;
+	hwif->atapi_dma = 1;
+
+	/* we support 80c cable only. */
+	hwif->udma_four = 1;
+
+	hwif->autodma = 0;
+	if (!noautodma)
+		hwif->autodma = 1;
+	hwif->drives[0].autodma = hwif->autodma;
+	hwif->drives[1].autodma = hwif->autodma;
+}
+
+#define DECLARE_SCC_DEV(name_str)			\
+  {							\
+      .name		= name_str,			\
+      .init_setup	= init_setup_scc,		\
+      .init_iops	= init_iops_scc,		\
+      .init_hwif	= init_hwif_scc,		\
+      .channels	= 1,					\
+      .autodma	= AUTODMA,				\
+      .bootable	= ON_BOARD,				\
+  }
+
+static ide_pci_device_t scc_chipsets[] __devinitdata = {
+	/* 0 */ DECLARE_SCC_DEV("sccIDE"),
+};
+
+/**
+ *	scc_init_one	-	pci layer discovery entry
+ *	@dev: PCI device
+ *	@id: ident table entry
+ *
+ *	Called by the PCI code when it finds an SCC PATA controller.
+ *	We then use the IDE PCI generic helper to do most of the work.
+ */
+
+static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	ide_pci_device_t *d = &scc_chipsets[id->driver_data];
+	return d->init_setup(dev, d);
+}
+
+/**
+ *	scc_remove	-	pci layer remove entry
+ *	@dev: PCI device
+ *
+ *	Called by the PCI code when it removes an SCC PATA controller.
+ */
+
+static void __devexit scc_remove(struct pci_dev *dev)
+{
+	struct scc_ports *ports = pci_get_drvdata(dev);
+	ide_hwif_t *hwif = &ide_hwifs[ports->hwif_id];
+	unsigned long ctl_base = pci_resource_start(dev, 0);
+	unsigned long dma_base = pci_resource_start(dev, 1);
+	unsigned long ctl_size = pci_resource_len(dev, 0);
+	unsigned long dma_size = pci_resource_len(dev, 1);
+
+	if (hwif->dmatable_cpu) {
+		pci_free_consistent(hwif->pci_dev,
+				    PRD_ENTRIES * PRD_BYTES,
+				    hwif->dmatable_cpu,
+				    hwif->dmatable_dma);
+		hwif->dmatable_cpu = NULL;
+	}
+
+	ide_unregister(hwif->index);
+
+	hwif->chipset = ide_unknown;
+	iounmap((void*)ports->dma);
+	iounmap((void*)ports->ctl);
+	release_mem_region(dma_base, dma_size);
+	release_mem_region(ctl_base, ctl_size);
+	memset(ports, 0, sizeof(*ports));
+}
+
+static struct pci_device_id scc_pci_tbl[] = {
+	{ PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ 0, },
+};
+MODULE_DEVICE_TABLE(pci, scc_pci_tbl);
+
+static struct pci_driver driver = {
+	.name = "SCC IDE",
+	.id_table = scc_pci_tbl,
+	.probe = scc_init_one,
+	.remove = scc_remove,
+};
+
+static int scc_ide_init(void)
+{
+	return ide_pci_register_driver(&driver);
+}
+
+module_init(scc_ide_init);
+/* -- No exit code?
+static void scc_ide_exit(void)
+{
+	ide_pci_unregister_driver(&driver);
+}
+module_exit(scc_ide_exit);
+ */
+
+
+MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE");
+MODULE_LICENSE("GPL");
diff --git a/drivers/ieee1394/ieee1394-ioctl.h b/drivers/ieee1394/ieee1394-ioctl.h
index 8f20750..46878fe 100644
--- a/drivers/ieee1394/ieee1394-ioctl.h
+++ b/drivers/ieee1394/ieee1394-ioctl.h
@@ -100,5 +100,7 @@
 	_IO  ('#', 0x28)
 #define RAW1394_IOC_ISO_RECV_FLUSH		\
 	_IO  ('#', 0x29)
+#define RAW1394_IOC_GET_CYCLE_TIMER		\
+	_IOR ('#', 0x30, struct raw1394_cycle_timer)
 
 #endif /* __IEEE1394_IOCTL_H */
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index 1521e57..d791d08 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -33,7 +33,10 @@
 #include <linux/skbuff.h>
 #include <linux/suspend.h>
 #include <linux/kthread.h>
+#include <linux/preempt.h>
+#include <linux/time.h>
 
+#include <asm/system.h>
 #include <asm/byteorder.h>
 
 #include "ieee1394_types.h"
@@ -186,6 +189,45 @@
 	}
 }
 
+/**
+ * hpsb_read_cycle_timer - read cycle timer register and system time
+ * @host: host whose isochronous cycle timer register is read
+ * @cycle_timer: address of bitfield to return the register contents
+ * @local_time: address to return the system time
+ *
+ * The format of * @cycle_timer, is described in OHCI 1.1 clause 5.13. This
+ * format is also read from non-OHCI controllers. * @local_time contains the
+ * system time in microseconds since the Epoch, read at the moment when the
+ * cycle timer was read.
+ *
+ * Return value: 0 for success or error number otherwise.
+ */
+int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer,
+			  u64 *local_time)
+{
+	int ctr;
+	struct timeval tv;
+	unsigned long flags;
+
+	if (!host || !cycle_timer || !local_time)
+		return -EINVAL;
+
+	preempt_disable();
+	local_irq_save(flags);
+
+	ctr = host->driver->devctl(host, GET_CYCLE_COUNTER, 0);
+	if (ctr)
+		do_gettimeofday(&tv);
+
+	local_irq_restore(flags);
+	preempt_enable();
+
+	if (!ctr)
+		return -EIO;
+	*cycle_timer = ctr;
+	*local_time = tv.tv_sec * 1000000ULL + tv.tv_usec;
+	return 0;
+}
 
 int hpsb_bus_reset(struct hpsb_host *host)
 {
@@ -1190,6 +1232,7 @@
 EXPORT_SYMBOL(hpsb_free_packet);
 EXPORT_SYMBOL(hpsb_send_packet);
 EXPORT_SYMBOL(hpsb_reset_bus);
+EXPORT_SYMBOL(hpsb_read_cycle_timer);
 EXPORT_SYMBOL(hpsb_bus_reset);
 EXPORT_SYMBOL(hpsb_selfid_received);
 EXPORT_SYMBOL(hpsb_selfid_complete);
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h
index 536ba3f..bd29d8e 100644
--- a/drivers/ieee1394/ieee1394_core.h
+++ b/drivers/ieee1394/ieee1394_core.h
@@ -127,6 +127,9 @@
  * progress, 0 otherwise. */
 int hpsb_reset_bus(struct hpsb_host *host, int type);
 
+int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer,
+			  u64 *local_time);
+
 /*
  * The following functions are exported for host driver module usage.  All of
  * them are safe to use in interrupt contexts, although some are quite
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index ba9faef..c5ace19 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -1681,7 +1681,8 @@
 	for (;;) {
 		/* Sleep until next bus reset */
 		set_current_state(TASK_INTERRUPTIBLE);
-		if (get_hpsb_generation(host) == generation)
+		if (get_hpsb_generation(host) == generation &&
+		    !kthread_should_stop())
 			schedule();
 		__set_current_state(TASK_RUNNING);
 
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index e982d60..06fac0d 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -180,7 +180,7 @@
 static void ohci1394_pci_remove(struct pci_dev *pdev);
 
 #ifndef __LITTLE_ENDIAN
-const static size_t hdr_sizes[] = {
+static const size_t hdr_sizes[] = {
 	3,	/* TCODE_WRITEQ */
 	4,	/* TCODE_WRITEB */
 	3,	/* TCODE_WRITE_RESPONSE */
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index aa9ca83..bb897a3 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -2669,6 +2669,18 @@
 	fi->iso_state = RAW1394_ISO_INACTIVE;
 }
 
+static int raw1394_read_cycle_timer(struct file_info *fi, void __user * uaddr)
+{
+	struct raw1394_cycle_timer ct;
+	int err;
+
+	err = hpsb_read_cycle_timer(fi->host, &ct.cycle_timer, &ct.local_time);
+	if (!err)
+		if (copy_to_user(uaddr, &ct, sizeof(ct)))
+			err = -EFAULT;
+	return err;
+}
+
 /* mmap the rawiso xmit/recv buffer */
 static int raw1394_mmap(struct file *file, struct vm_area_struct *vma)
 {
@@ -2777,6 +2789,14 @@
 		break;
 	}
 
+	/* state-independent commands */
+	switch(cmd) {
+	case RAW1394_IOC_GET_CYCLE_TIMER:
+		return raw1394_read_cycle_timer(fi, argp);
+	default:
+		break;
+	}
+
 	return -EINVAL;
 }
 
diff --git a/drivers/ieee1394/raw1394.h b/drivers/ieee1394/raw1394.h
index 35bfc38..7bd22ee 100644
--- a/drivers/ieee1394/raw1394.h
+++ b/drivers/ieee1394/raw1394.h
@@ -178,4 +178,14 @@
 	__s16 xmit_cycle;
 };
 
+/* argument to RAW1394_IOC_GET_CYCLE_TIMER ioctl */
+struct raw1394_cycle_timer {
+	/* contents of Isochronous Cycle Timer register,
+	   as in OHCI 1.1 clause 5.13 (also with non-OHCI hosts) */
+	__u32 cycle_timer;
+
+	/* local time in microseconds since Epoch,
+	   simultaneously read with cycle timer */
+	__u64 local_time;
+};
 #endif /* IEEE1394_RAW1394_H */
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
index 50fb1cd..189e5d4 100644
--- a/drivers/infiniband/core/Makefile
+++ b/drivers/infiniband/core/Makefile
@@ -12,7 +12,7 @@
 
 ib_mad-y :=			mad.o smi.o agent.o mad_rmpp.o
 
-ib_sa-y :=			sa_query.o
+ib_sa-y :=			sa_query.o multicast.o
 
 ib_cm-y :=			cm.o
 
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index db88e60..f8d69b3 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -71,6 +71,7 @@
 static DEFINE_IDR(sdp_ps);
 static DEFINE_IDR(tcp_ps);
 static DEFINE_IDR(udp_ps);
+static DEFINE_IDR(ipoib_ps);
 static int next_port;
 
 struct cma_device {
@@ -116,6 +117,7 @@
 	struct list_head	list;
 	struct list_head	listen_list;
 	struct cma_device	*cma_dev;
+	struct list_head	mc_list;
 
 	enum cma_state		state;
 	spinlock_t		lock;
@@ -134,10 +136,23 @@
 	} cm_id;
 
 	u32			seq_num;
+	u32			qkey;
 	u32			qp_num;
 	u8			srq;
 };
 
+struct cma_multicast {
+	struct rdma_id_private *id_priv;
+	union {
+		struct ib_sa_multicast *ib;
+	} multicast;
+	struct list_head	list;
+	void			*context;
+	struct sockaddr		addr;
+	u8			pad[sizeof(struct sockaddr_in6) -
+				    sizeof(struct sockaddr)];
+};
+
 struct cma_work {
 	struct work_struct	work;
 	struct rdma_id_private	*id;
@@ -243,6 +258,11 @@
 	hh->ip_version = (ip_ver << 4) | (hh->ip_version & 0xF);
 }
 
+static inline int cma_is_ud_ps(enum rdma_port_space ps)
+{
+	return (ps == RDMA_PS_UDP || ps == RDMA_PS_IPOIB);
+}
+
 static void cma_attach_to_dev(struct rdma_id_private *id_priv,
 			      struct cma_device *cma_dev)
 {
@@ -265,19 +285,41 @@
 	id_priv->cma_dev = NULL;
 }
 
+static int cma_set_qkey(struct ib_device *device, u8 port_num,
+			enum rdma_port_space ps,
+			struct rdma_dev_addr *dev_addr, u32 *qkey)
+{
+	struct ib_sa_mcmember_rec rec;
+	int ret = 0;
+
+	switch (ps) {
+	case RDMA_PS_UDP:
+		*qkey = RDMA_UDP_QKEY;
+		break;
+	case RDMA_PS_IPOIB:
+		ib_addr_get_mgid(dev_addr, &rec.mgid);
+		ret = ib_sa_get_mcmember_rec(device, port_num, &rec.mgid, &rec);
+		*qkey = be32_to_cpu(rec.qkey);
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
+
 static int cma_acquire_dev(struct rdma_id_private *id_priv)
 {
-	enum rdma_node_type dev_type = id_priv->id.route.addr.dev_addr.dev_type;
+	struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
 	struct cma_device *cma_dev;
 	union ib_gid gid;
 	int ret = -ENODEV;
 
-	switch (rdma_node_get_transport(dev_type)) {
+	switch (rdma_node_get_transport(dev_addr->dev_type)) {
 	case RDMA_TRANSPORT_IB:
-		ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid);
+		ib_addr_get_sgid(dev_addr, &gid);
 		break;
 	case RDMA_TRANSPORT_IWARP:
-		iw_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid);
+		iw_addr_get_sgid(dev_addr, &gid);
 		break;
 	default:
 		return -ENODEV;
@@ -287,7 +329,12 @@
 		ret = ib_find_cached_gid(cma_dev->device, &gid,
 					 &id_priv->id.port_num, NULL);
 		if (!ret) {
-			cma_attach_to_dev(id_priv, cma_dev);
+			ret = cma_set_qkey(cma_dev->device,
+					   id_priv->id.port_num,
+					   id_priv->id.ps, dev_addr,
+					   &id_priv->qkey);
+			if (!ret)
+				cma_attach_to_dev(id_priv, cma_dev);
 			break;
 		}
 	}
@@ -325,40 +372,50 @@
 	init_waitqueue_head(&id_priv->wait_remove);
 	atomic_set(&id_priv->dev_remove, 0);
 	INIT_LIST_HEAD(&id_priv->listen_list);
+	INIT_LIST_HEAD(&id_priv->mc_list);
 	get_random_bytes(&id_priv->seq_num, sizeof id_priv->seq_num);
 
 	return &id_priv->id;
 }
 EXPORT_SYMBOL(rdma_create_id);
 
-static int cma_init_ib_qp(struct rdma_id_private *id_priv, struct ib_qp *qp)
+static int cma_init_ud_qp(struct rdma_id_private *id_priv, struct ib_qp *qp)
 {
 	struct ib_qp_attr qp_attr;
-	struct rdma_dev_addr *dev_addr;
-	int ret;
+	int qp_attr_mask, ret;
 
-	dev_addr = &id_priv->id.route.addr.dev_addr;
-	ret = ib_find_cached_pkey(id_priv->id.device, id_priv->id.port_num,
-				  ib_addr_get_pkey(dev_addr),
-				  &qp_attr.pkey_index);
+	qp_attr.qp_state = IB_QPS_INIT;
+	ret = rdma_init_qp_attr(&id_priv->id, &qp_attr, &qp_attr_mask);
 	if (ret)
 		return ret;
 
-	qp_attr.qp_state = IB_QPS_INIT;
-	qp_attr.qp_access_flags = 0;
-	qp_attr.port_num = id_priv->id.port_num;
-	return ib_modify_qp(qp, &qp_attr, IB_QP_STATE | IB_QP_ACCESS_FLAGS |
-					  IB_QP_PKEY_INDEX | IB_QP_PORT);
+	ret = ib_modify_qp(qp, &qp_attr, qp_attr_mask);
+	if (ret)
+		return ret;
+
+	qp_attr.qp_state = IB_QPS_RTR;
+	ret = ib_modify_qp(qp, &qp_attr, IB_QP_STATE);
+	if (ret)
+		return ret;
+
+	qp_attr.qp_state = IB_QPS_RTS;
+	qp_attr.sq_psn = 0;
+	ret = ib_modify_qp(qp, &qp_attr, IB_QP_STATE | IB_QP_SQ_PSN);
+
+	return ret;
 }
 
-static int cma_init_iw_qp(struct rdma_id_private *id_priv, struct ib_qp *qp)
+static int cma_init_conn_qp(struct rdma_id_private *id_priv, struct ib_qp *qp)
 {
 	struct ib_qp_attr qp_attr;
+	int qp_attr_mask, ret;
 
 	qp_attr.qp_state = IB_QPS_INIT;
-	qp_attr.qp_access_flags = IB_ACCESS_LOCAL_WRITE;
+	ret = rdma_init_qp_attr(&id_priv->id, &qp_attr, &qp_attr_mask);
+	if (ret)
+		return ret;
 
-	return ib_modify_qp(qp, &qp_attr, IB_QP_STATE | IB_QP_ACCESS_FLAGS);
+	return ib_modify_qp(qp, &qp_attr, qp_attr_mask);
 }
 
 int rdma_create_qp(struct rdma_cm_id *id, struct ib_pd *pd,
@@ -376,18 +433,10 @@
 	if (IS_ERR(qp))
 		return PTR_ERR(qp);
 
-	switch (rdma_node_get_transport(id->device->node_type)) {
-	case RDMA_TRANSPORT_IB:
-		ret = cma_init_ib_qp(id_priv, qp);
-		break;
-	case RDMA_TRANSPORT_IWARP:
-		ret = cma_init_iw_qp(id_priv, qp);
-		break;
-	default:
-		ret = -ENOSYS;
-		break;
-	}
-
+	if (cma_is_ud_ps(id_priv->id.ps))
+		ret = cma_init_ud_qp(id_priv, qp);
+	else
+		ret = cma_init_conn_qp(id_priv, qp);
 	if (ret)
 		goto err;
 
@@ -460,23 +509,55 @@
 	return ib_modify_qp(id->qp, &qp_attr, IB_QP_STATE);
 }
 
+static int cma_ib_init_qp_attr(struct rdma_id_private *id_priv,
+			       struct ib_qp_attr *qp_attr, int *qp_attr_mask)
+{
+	struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
+	int ret;
+
+	ret = ib_find_cached_pkey(id_priv->id.device, id_priv->id.port_num,
+				  ib_addr_get_pkey(dev_addr),
+				  &qp_attr->pkey_index);
+	if (ret)
+		return ret;
+
+	qp_attr->port_num = id_priv->id.port_num;
+	*qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT;
+
+	if (cma_is_ud_ps(id_priv->id.ps)) {
+		qp_attr->qkey = id_priv->qkey;
+		*qp_attr_mask |= IB_QP_QKEY;
+	} else {
+		qp_attr->qp_access_flags = 0;
+		*qp_attr_mask |= IB_QP_ACCESS_FLAGS;
+	}
+	return 0;
+}
+
 int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr,
 		       int *qp_attr_mask)
 {
 	struct rdma_id_private *id_priv;
-	int ret;
+	int ret = 0;
 
 	id_priv = container_of(id, struct rdma_id_private, id);
 	switch (rdma_node_get_transport(id_priv->id.device->node_type)) {
 	case RDMA_TRANSPORT_IB:
-		ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, qp_attr,
-					 qp_attr_mask);
+		if (!id_priv->cm_id.ib || cma_is_ud_ps(id_priv->id.ps))
+			ret = cma_ib_init_qp_attr(id_priv, qp_attr, qp_attr_mask);
+		else
+			ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, qp_attr,
+						 qp_attr_mask);
 		if (qp_attr->qp_state == IB_QPS_RTR)
 			qp_attr->rq_psn = id_priv->seq_num;
 		break;
 	case RDMA_TRANSPORT_IWARP:
-		ret = iw_cm_init_qp_attr(id_priv->cm_id.iw, qp_attr,
-					qp_attr_mask);
+		if (!id_priv->cm_id.iw) {
+			qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE;
+			*qp_attr_mask = IB_QP_STATE | IB_QP_ACCESS_FLAGS;
+		} else
+			ret = iw_cm_init_qp_attr(id_priv->cm_id.iw, qp_attr,
+						 qp_attr_mask);
 		break;
 	default:
 		ret = -ENOSYS;
@@ -698,6 +779,19 @@
 	mutex_unlock(&lock);
 }
 
+static void cma_leave_mc_groups(struct rdma_id_private *id_priv)
+{
+	struct cma_multicast *mc;
+
+	while (!list_empty(&id_priv->mc_list)) {
+		mc = container_of(id_priv->mc_list.next,
+				  struct cma_multicast, list);
+		list_del(&mc->list);
+		ib_sa_free_multicast(mc->multicast.ib);
+		kfree(mc);
+	}
+}
+
 void rdma_destroy_id(struct rdma_cm_id *id)
 {
 	struct rdma_id_private *id_priv;
@@ -722,6 +816,7 @@
 		default:
 			break;
 		}
+		cma_leave_mc_groups(id_priv);
 		mutex_lock(&lock);
 		cma_detach_from_dev(id_priv);
 	}
@@ -972,7 +1067,7 @@
 	memset(&event, 0, sizeof event);
 	offset = cma_user_data_offset(listen_id->id.ps);
 	event.event = RDMA_CM_EVENT_CONNECT_REQUEST;
-	if (listen_id->id.ps == RDMA_PS_UDP) {
+	if (cma_is_ud_ps(listen_id->id.ps)) {
 		conn_id = cma_new_udp_id(&listen_id->id, ib_event);
 		event.param.ud.private_data = ib_event->private_data + offset;
 		event.param.ud.private_data_len =
@@ -1725,7 +1820,7 @@
 	struct rdma_bind_list *bind_list;
 	int port, ret;
 
-	bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL);
+	bind_list = kmalloc(sizeof *bind_list, GFP_KERNEL);
 	if (!bind_list)
 		return -ENOMEM;
 
@@ -1847,6 +1942,9 @@
 	case RDMA_PS_UDP:
 		ps = &udp_ps;
 		break;
+	case RDMA_PS_IPOIB:
+		ps = &ipoib_ps;
+		break;
 	default:
 		return -EPROTONOSUPPORT;
 	}
@@ -1961,7 +2059,7 @@
 			event.status = ib_event->param.sidr_rep_rcvd.status;
 			break;
 		}
-		if (rep->qkey != RDMA_UD_QKEY) {
+		if (id_priv->qkey != rep->qkey) {
 			event.event = RDMA_CM_EVENT_UNREACHABLE;
 			event.status = -EINVAL;
 			break;
@@ -2160,7 +2258,7 @@
 
 	switch (rdma_node_get_transport(id->device->node_type)) {
 	case RDMA_TRANSPORT_IB:
-		if (id->ps == RDMA_PS_UDP)
+		if (cma_is_ud_ps(id->ps))
 			ret = cma_resolve_ib_udp(id_priv, conn_param);
 		else
 			ret = cma_connect_ib(id_priv, conn_param);
@@ -2256,7 +2354,7 @@
 	rep.status = status;
 	if (status == IB_SIDR_SUCCESS) {
 		rep.qp_num = id_priv->qp_num;
-		rep.qkey = RDMA_UD_QKEY;
+		rep.qkey = id_priv->qkey;
 	}
 	rep.private_data = private_data;
 	rep.private_data_len = private_data_len;
@@ -2280,7 +2378,7 @@
 
 	switch (rdma_node_get_transport(id->device->node_type)) {
 	case RDMA_TRANSPORT_IB:
-		if (id->ps == RDMA_PS_UDP)
+		if (cma_is_ud_ps(id->ps))
 			ret = cma_send_sidr_rep(id_priv, IB_SIDR_SUCCESS,
 						conn_param->private_data,
 						conn_param->private_data_len);
@@ -2341,7 +2439,7 @@
 
 	switch (rdma_node_get_transport(id->device->node_type)) {
 	case RDMA_TRANSPORT_IB:
-		if (id->ps == RDMA_PS_UDP)
+		if (cma_is_ud_ps(id->ps))
 			ret = cma_send_sidr_rep(id_priv, IB_SIDR_REJECT,
 						private_data, private_data_len);
 		else
@@ -2392,6 +2490,178 @@
 }
 EXPORT_SYMBOL(rdma_disconnect);
 
+static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast)
+{
+	struct rdma_id_private *id_priv;
+	struct cma_multicast *mc = multicast->context;
+	struct rdma_cm_event event;
+	int ret;
+
+	id_priv = mc->id_priv;
+	atomic_inc(&id_priv->dev_remove);
+	if (!cma_comp(id_priv, CMA_ADDR_BOUND) &&
+	    !cma_comp(id_priv, CMA_ADDR_RESOLVED))
+		goto out;
+
+	if (!status && id_priv->id.qp)
+		status = ib_attach_mcast(id_priv->id.qp, &multicast->rec.mgid,
+					 multicast->rec.mlid);
+
+	memset(&event, 0, sizeof event);
+	event.status = status;
+	event.param.ud.private_data = mc->context;
+	if (!status) {
+		event.event = RDMA_CM_EVENT_MULTICAST_JOIN;
+		ib_init_ah_from_mcmember(id_priv->id.device,
+					 id_priv->id.port_num, &multicast->rec,
+					 &event.param.ud.ah_attr);
+		event.param.ud.qp_num = 0xFFFFFF;
+		event.param.ud.qkey = be32_to_cpu(multicast->rec.qkey);
+	} else
+		event.event = RDMA_CM_EVENT_MULTICAST_ERROR;
+
+	ret = id_priv->id.event_handler(&id_priv->id, &event);
+	if (ret) {
+		cma_exch(id_priv, CMA_DESTROYING);
+		cma_release_remove(id_priv);
+		rdma_destroy_id(&id_priv->id);
+		return 0;
+	}
+out:
+	cma_release_remove(id_priv);
+	return 0;
+}
+
+static void cma_set_mgid(struct rdma_id_private *id_priv,
+			 struct sockaddr *addr, union ib_gid *mgid)
+{
+	unsigned char mc_map[MAX_ADDR_LEN];
+	struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
+	struct sockaddr_in *sin = (struct sockaddr_in *) addr;
+	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) addr;
+
+	if (cma_any_addr(addr)) {
+		memset(mgid, 0, sizeof *mgid);
+	} else if ((addr->sa_family == AF_INET6) &&
+		   ((be32_to_cpu(sin6->sin6_addr.s6_addr32[0]) & 0xFF10A01B) ==
+								 0xFF10A01B)) {
+		/* IPv6 address is an SA assigned MGID. */
+		memcpy(mgid, &sin6->sin6_addr, sizeof *mgid);
+	} else {
+		ip_ib_mc_map(sin->sin_addr.s_addr, mc_map);
+		if (id_priv->id.ps == RDMA_PS_UDP)
+			mc_map[7] = 0x01;	/* Use RDMA CM signature */
+		mc_map[8] = ib_addr_get_pkey(dev_addr) >> 8;
+		mc_map[9] = (unsigned char) ib_addr_get_pkey(dev_addr);
+		*mgid = *(union ib_gid *) (mc_map + 4);
+	}
+}
+
+static int cma_join_ib_multicast(struct rdma_id_private *id_priv,
+				 struct cma_multicast *mc)
+{
+	struct ib_sa_mcmember_rec rec;
+	struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
+	ib_sa_comp_mask comp_mask;
+	int ret;
+
+	ib_addr_get_mgid(dev_addr, &rec.mgid);
+	ret = ib_sa_get_mcmember_rec(id_priv->id.device, id_priv->id.port_num,
+				     &rec.mgid, &rec);
+	if (ret)
+		return ret;
+
+	cma_set_mgid(id_priv, &mc->addr, &rec.mgid);
+	if (id_priv->id.ps == RDMA_PS_UDP)
+		rec.qkey = cpu_to_be32(RDMA_UDP_QKEY);
+	ib_addr_get_sgid(dev_addr, &rec.port_gid);
+	rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr));
+	rec.join_state = 1;
+
+	comp_mask = IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID |
+		    IB_SA_MCMEMBER_REC_PKEY | IB_SA_MCMEMBER_REC_JOIN_STATE |
+		    IB_SA_MCMEMBER_REC_QKEY | IB_SA_MCMEMBER_REC_SL |
+		    IB_SA_MCMEMBER_REC_FLOW_LABEL |
+		    IB_SA_MCMEMBER_REC_TRAFFIC_CLASS;
+
+	mc->multicast.ib = ib_sa_join_multicast(&sa_client, id_priv->id.device,
+						id_priv->id.port_num, &rec,
+						comp_mask, GFP_KERNEL,
+						cma_ib_mc_handler, mc);
+	if (IS_ERR(mc->multicast.ib))
+		return PTR_ERR(mc->multicast.ib);
+
+	return 0;
+}
+
+int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
+			void *context)
+{
+	struct rdma_id_private *id_priv;
+	struct cma_multicast *mc;
+	int ret;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (!cma_comp(id_priv, CMA_ADDR_BOUND) &&
+	    !cma_comp(id_priv, CMA_ADDR_RESOLVED))
+		return -EINVAL;
+
+	mc = kmalloc(sizeof *mc, GFP_KERNEL);
+	if (!mc)
+		return -ENOMEM;
+
+	memcpy(&mc->addr, addr, ip_addr_size(addr));
+	mc->context = context;
+	mc->id_priv = id_priv;
+
+	spin_lock(&id_priv->lock);
+	list_add(&mc->list, &id_priv->mc_list);
+	spin_unlock(&id_priv->lock);
+
+	switch (rdma_node_get_transport(id->device->node_type)) {
+	case RDMA_TRANSPORT_IB:
+		ret = cma_join_ib_multicast(id_priv, mc);
+		break;
+	default:
+		ret = -ENOSYS;
+		break;
+	}
+
+	if (ret) {
+		spin_lock_irq(&id_priv->lock);
+		list_del(&mc->list);
+		spin_unlock_irq(&id_priv->lock);
+		kfree(mc);
+	}
+	return ret;
+}
+EXPORT_SYMBOL(rdma_join_multicast);
+
+void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr)
+{
+	struct rdma_id_private *id_priv;
+	struct cma_multicast *mc;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	spin_lock_irq(&id_priv->lock);
+	list_for_each_entry(mc, &id_priv->mc_list, list) {
+		if (!memcmp(&mc->addr, addr, ip_addr_size(addr))) {
+			list_del(&mc->list);
+			spin_unlock_irq(&id_priv->lock);
+
+			if (id->qp)
+				ib_detach_mcast(id->qp,
+						&mc->multicast.ib->rec.mgid,
+						mc->multicast.ib->rec.mlid);
+			ib_sa_free_multicast(mc->multicast.ib);
+			kfree(mc);
+			return;
+		}
+	}
+	spin_unlock_irq(&id_priv->lock);
+}
+EXPORT_SYMBOL(rdma_leave_multicast);
+
 static void cma_add_one(struct ib_device *device)
 {
 	struct cma_device *cma_dev;
@@ -2522,6 +2792,7 @@
 	idr_destroy(&sdp_ps);
 	idr_destroy(&tcp_ps);
 	idr_destroy(&udp_ps);
+	idr_destroy(&ipoib_ps);
 }
 
 module_init(cma_init);
diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c
index 8926a2b..1d796e7 100644
--- a/drivers/infiniband/core/fmr_pool.c
+++ b/drivers/infiniband/core/fmr_pool.c
@@ -301,7 +301,7 @@
 
 	{
 		struct ib_pool_fmr *fmr;
-		struct ib_fmr_attr attr = {
+		struct ib_fmr_attr fmr_attr = {
 			.max_pages  = params->max_pages_per_fmr,
 			.max_maps   = pool->max_remaps,
 			.page_shift = params->page_shift
@@ -321,7 +321,7 @@
 			fmr->ref_count        = 0;
 			INIT_HLIST_NODE(&fmr->cache_node);
 
-			fmr->fmr = ib_alloc_fmr(pd, params->access, &attr);
+			fmr->fmr = ib_alloc_fmr(pd, params->access, &fmr_attr);
 			if (IS_ERR(fmr->fmr)) {
 				printk(KERN_WARNING "fmr_create failed for FMR %d", i);
 				kfree(fmr);
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
index 1039ad5..891d1fa 100644
--- a/drivers/infiniband/core/iwcm.c
+++ b/drivers/infiniband/core/iwcm.c
@@ -146,6 +146,12 @@
 	return 0;
 }
 
+static void free_cm_id(struct iwcm_id_private *cm_id_priv)
+{
+	dealloc_work_entries(cm_id_priv);
+	kfree(cm_id_priv);
+}
+
 /*
  * Release a reference on cm_id. If the last reference is being
  * released, enable the waiting thread (in iw_destroy_cm_id) to
@@ -153,21 +159,14 @@
  */
 static int iwcm_deref_id(struct iwcm_id_private *cm_id_priv)
 {
-	int ret = 0;
-
 	BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
 	if (atomic_dec_and_test(&cm_id_priv->refcount)) {
 		BUG_ON(!list_empty(&cm_id_priv->work_list));
-		if (waitqueue_active(&cm_id_priv->destroy_comp.wait)) {
-			BUG_ON(cm_id_priv->state != IW_CM_STATE_DESTROYING);
-			BUG_ON(test_bit(IWCM_F_CALLBACK_DESTROY,
-					&cm_id_priv->flags));
-			ret = 1;
-		}
 		complete(&cm_id_priv->destroy_comp);
+		return 1;
 	}
 
-	return ret;
+	return 0;
 }
 
 static void add_ref(struct iw_cm_id *cm_id)
@@ -181,7 +180,11 @@
 {
 	struct iwcm_id_private *cm_id_priv;
 	cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
-	iwcm_deref_id(cm_id_priv);
+	if (iwcm_deref_id(cm_id_priv) &&
+	    test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags)) {
+		BUG_ON(!list_empty(&cm_id_priv->work_list));
+		free_cm_id(cm_id_priv);
+	}
 }
 
 static int cm_event_handler(struct iw_cm_id *cm_id, struct iw_cm_event *event);
@@ -355,7 +358,9 @@
 	case IW_CM_STATE_CONN_RECV:
 		/*
 		 * App called destroy before/without calling accept after
-		 * receiving connection request event notification.
+		 * receiving connection request event notification or
+		 * returned non zero from the event callback function.
+		 * In either case, must tell the provider to reject.
 		 */
 		cm_id_priv->state = IW_CM_STATE_DESTROYING;
 		break;
@@ -391,9 +396,7 @@
 
 	wait_for_completion(&cm_id_priv->destroy_comp);
 
-	dealloc_work_entries(cm_id_priv);
-
-	kfree(cm_id_priv);
+	free_cm_id(cm_id_priv);
 }
 EXPORT_SYMBOL(iw_destroy_cm_id);
 
@@ -647,10 +650,11 @@
 	/* Call the client CM handler */
 	ret = cm_id->cm_handler(cm_id, iw_event);
 	if (ret) {
+		iw_cm_reject(cm_id, NULL, 0);
 		set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
 		destroy_cm_id(cm_id);
 		if (atomic_read(&cm_id_priv->refcount)==0)
-			kfree(cm_id);
+			free_cm_id(cm_id_priv);
 	}
 
 out:
@@ -854,13 +858,12 @@
 			destroy_cm_id(&cm_id_priv->id);
 		}
 		BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
-		if (iwcm_deref_id(cm_id_priv))
-			return;
-
-		if (atomic_read(&cm_id_priv->refcount)==0 &&
-		    test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags)) {
-			dealloc_work_entries(cm_id_priv);
-			kfree(cm_id_priv);
+		if (iwcm_deref_id(cm_id_priv)) {
+			if (test_bit(IWCM_F_CALLBACK_DESTROY,
+				     &cm_id_priv->flags)) {
+				BUG_ON(!list_empty(&cm_id_priv->work_list));
+				free_cm_id(cm_id_priv);
+			}
 			return;
 		}
 		spin_lock_irqsave(&cm_id_priv->lock, flags);
diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c
new file mode 100644
index 0000000..4a579b3
--- /dev/null
+++ b/drivers/infiniband/core/multicast.c
@@ -0,0 +1,837 @@
+/*
+ * Copyright (c) 2006 Intel Corporation.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/completion.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/bitops.h>
+#include <linux/random.h>
+
+#include <rdma/ib_cache.h>
+#include "sa.h"
+
+static void mcast_add_one(struct ib_device *device);
+static void mcast_remove_one(struct ib_device *device);
+
+static struct ib_client mcast_client = {
+	.name   = "ib_multicast",
+	.add    = mcast_add_one,
+	.remove = mcast_remove_one
+};
+
+static struct ib_sa_client	sa_client;
+static struct workqueue_struct	*mcast_wq;
+static union ib_gid mgid0;
+
+struct mcast_device;
+
+struct mcast_port {
+	struct mcast_device	*dev;
+	spinlock_t		lock;
+	struct rb_root		table;
+	atomic_t		refcount;
+	struct completion	comp;
+	u8			port_num;
+};
+
+struct mcast_device {
+	struct ib_device	*device;
+	struct ib_event_handler	event_handler;
+	int			start_port;
+	int			end_port;
+	struct mcast_port	port[0];
+};
+
+enum mcast_state {
+	MCAST_IDLE,
+	MCAST_JOINING,
+	MCAST_MEMBER,
+	MCAST_BUSY,
+	MCAST_ERROR
+};
+
+struct mcast_member;
+
+struct mcast_group {
+	struct ib_sa_mcmember_rec rec;
+	struct rb_node		node;
+	struct mcast_port	*port;
+	spinlock_t		lock;
+	struct work_struct	work;
+	struct list_head	pending_list;
+	struct list_head	active_list;
+	struct mcast_member	*last_join;
+	int			members[3];
+	atomic_t		refcount;
+	enum mcast_state	state;
+	struct ib_sa_query	*query;
+	int			query_id;
+};
+
+struct mcast_member {
+	struct ib_sa_multicast	multicast;
+	struct ib_sa_client	*client;
+	struct mcast_group	*group;
+	struct list_head	list;
+	enum mcast_state	state;
+	atomic_t		refcount;
+	struct completion	comp;
+};
+
+static void join_handler(int status, struct ib_sa_mcmember_rec *rec,
+			 void *context);
+static void leave_handler(int status, struct ib_sa_mcmember_rec *rec,
+			  void *context);
+
+static struct mcast_group *mcast_find(struct mcast_port *port,
+				      union ib_gid *mgid)
+{
+	struct rb_node *node = port->table.rb_node;
+	struct mcast_group *group;
+	int ret;
+
+	while (node) {
+		group = rb_entry(node, struct mcast_group, node);
+		ret = memcmp(mgid->raw, group->rec.mgid.raw, sizeof *mgid);
+		if (!ret)
+			return group;
+
+		if (ret < 0)
+			node = node->rb_left;
+		else
+			node = node->rb_right;
+	}
+	return NULL;
+}
+
+static struct mcast_group *mcast_insert(struct mcast_port *port,
+					struct mcast_group *group,
+					int allow_duplicates)
+{
+	struct rb_node **link = &port->table.rb_node;
+	struct rb_node *parent = NULL;
+	struct mcast_group *cur_group;
+	int ret;
+
+	while (*link) {
+		parent = *link;
+		cur_group = rb_entry(parent, struct mcast_group, node);
+
+		ret = memcmp(group->rec.mgid.raw, cur_group->rec.mgid.raw,
+			     sizeof group->rec.mgid);
+		if (ret < 0)
+			link = &(*link)->rb_left;
+		else if (ret > 0)
+			link = &(*link)->rb_right;
+		else if (allow_duplicates)
+			link = &(*link)->rb_left;
+		else
+			return cur_group;
+	}
+	rb_link_node(&group->node, parent, link);
+	rb_insert_color(&group->node, &port->table);
+	return NULL;
+}
+
+static void deref_port(struct mcast_port *port)
+{
+	if (atomic_dec_and_test(&port->refcount))
+		complete(&port->comp);
+}
+
+static void release_group(struct mcast_group *group)
+{
+	struct mcast_port *port = group->port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	if (atomic_dec_and_test(&group->refcount)) {
+		rb_erase(&group->node, &port->table);
+		spin_unlock_irqrestore(&port->lock, flags);
+		kfree(group);
+		deref_port(port);
+	} else
+		spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void deref_member(struct mcast_member *member)
+{
+	if (atomic_dec_and_test(&member->refcount))
+		complete(&member->comp);
+}
+
+static void queue_join(struct mcast_member *member)
+{
+	struct mcast_group *group = member->group;
+	unsigned long flags;
+
+	spin_lock_irqsave(&group->lock, flags);
+	list_add(&member->list, &group->pending_list);
+	if (group->state == MCAST_IDLE) {
+		group->state = MCAST_BUSY;
+		atomic_inc(&group->refcount);
+		queue_work(mcast_wq, &group->work);
+	}
+	spin_unlock_irqrestore(&group->lock, flags);
+}
+
+/*
+ * A multicast group has three types of members: full member, non member, and
+ * send only member.  We need to keep track of the number of members of each
+ * type based on their join state.  Adjust the number of members the belong to
+ * the specified join states.
+ */
+static void adjust_membership(struct mcast_group *group, u8 join_state, int inc)
+{
+	int i;
+
+	for (i = 0; i < 3; i++, join_state >>= 1)
+		if (join_state & 0x1)
+			group->members[i] += inc;
+}
+
+/*
+ * If a multicast group has zero members left for a particular join state, but
+ * the group is still a member with the SA, we need to leave that join state.
+ * Determine which join states we still belong to, but that do not have any
+ * active members.
+ */
+static u8 get_leave_state(struct mcast_group *group)
+{
+	u8 leave_state = 0;
+	int i;
+
+	for (i = 0; i < 3; i++)
+		if (!group->members[i])
+			leave_state |= (0x1 << i);
+
+	return leave_state & group->rec.join_state;
+}
+
+static int check_selector(ib_sa_comp_mask comp_mask,
+			  ib_sa_comp_mask selector_mask,
+			  ib_sa_comp_mask value_mask,
+			  u8 selector, u8 src_value, u8 dst_value)
+{
+	int err;
+
+	if (!(comp_mask & selector_mask) || !(comp_mask & value_mask))
+		return 0;
+
+	switch (selector) {
+	case IB_SA_GT:
+		err = (src_value <= dst_value);
+		break;
+	case IB_SA_LT:
+		err = (src_value >= dst_value);
+		break;
+	case IB_SA_EQ:
+		err = (src_value != dst_value);
+		break;
+	default:
+		err = 0;
+		break;
+	}
+
+	return err;
+}
+
+static int cmp_rec(struct ib_sa_mcmember_rec *src,
+		   struct ib_sa_mcmember_rec *dst, ib_sa_comp_mask comp_mask)
+{
+	/* MGID must already match */
+
+	if (comp_mask & IB_SA_MCMEMBER_REC_PORT_GID &&
+	    memcmp(&src->port_gid, &dst->port_gid, sizeof src->port_gid))
+		return -EINVAL;
+	if (comp_mask & IB_SA_MCMEMBER_REC_QKEY && src->qkey != dst->qkey)
+		return -EINVAL;
+	if (comp_mask & IB_SA_MCMEMBER_REC_MLID && src->mlid != dst->mlid)
+		return -EINVAL;
+	if (check_selector(comp_mask, IB_SA_MCMEMBER_REC_MTU_SELECTOR,
+			   IB_SA_MCMEMBER_REC_MTU, dst->mtu_selector,
+			   src->mtu, dst->mtu))
+		return -EINVAL;
+	if (comp_mask & IB_SA_MCMEMBER_REC_TRAFFIC_CLASS &&
+	    src->traffic_class != dst->traffic_class)
+		return -EINVAL;
+	if (comp_mask & IB_SA_MCMEMBER_REC_PKEY && src->pkey != dst->pkey)
+		return -EINVAL;
+	if (check_selector(comp_mask, IB_SA_MCMEMBER_REC_RATE_SELECTOR,
+			   IB_SA_MCMEMBER_REC_RATE, dst->rate_selector,
+			   src->rate, dst->rate))
+		return -EINVAL;
+	if (check_selector(comp_mask,
+			   IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME_SELECTOR,
+			   IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME,
+			   dst->packet_life_time_selector,
+			   src->packet_life_time, dst->packet_life_time))
+		return -EINVAL;
+	if (comp_mask & IB_SA_MCMEMBER_REC_SL && src->sl != dst->sl)
+		return -EINVAL;
+	if (comp_mask & IB_SA_MCMEMBER_REC_FLOW_LABEL &&
+	    src->flow_label != dst->flow_label)
+		return -EINVAL;
+	if (comp_mask & IB_SA_MCMEMBER_REC_HOP_LIMIT &&
+	    src->hop_limit != dst->hop_limit)
+		return -EINVAL;
+	if (comp_mask & IB_SA_MCMEMBER_REC_SCOPE && src->scope != dst->scope)
+		return -EINVAL;
+
+	/* join_state checked separately, proxy_join ignored */
+
+	return 0;
+}
+
+static int send_join(struct mcast_group *group, struct mcast_member *member)
+{
+	struct mcast_port *port = group->port;
+	int ret;
+
+	group->last_join = member;
+	ret = ib_sa_mcmember_rec_query(&sa_client, port->dev->device,
+				       port->port_num, IB_MGMT_METHOD_SET,
+				       &member->multicast.rec,
+				       member->multicast.comp_mask,
+				       3000, GFP_KERNEL, join_handler, group,
+				       &group->query);
+	if (ret >= 0) {
+		group->query_id = ret;
+		ret = 0;
+	}
+	return ret;
+}
+
+static int send_leave(struct mcast_group *group, u8 leave_state)
+{
+	struct mcast_port *port = group->port;
+	struct ib_sa_mcmember_rec rec;
+	int ret;
+
+	rec = group->rec;
+	rec.join_state = leave_state;
+
+	ret = ib_sa_mcmember_rec_query(&sa_client, port->dev->device,
+				       port->port_num, IB_SA_METHOD_DELETE, &rec,
+				       IB_SA_MCMEMBER_REC_MGID     |
+				       IB_SA_MCMEMBER_REC_PORT_GID |
+				       IB_SA_MCMEMBER_REC_JOIN_STATE,
+				       3000, GFP_KERNEL, leave_handler,
+				       group, &group->query);
+	if (ret >= 0) {
+		group->query_id = ret;
+		ret = 0;
+	}
+	return ret;
+}
+
+static void join_group(struct mcast_group *group, struct mcast_member *member,
+		       u8 join_state)
+{
+	member->state = MCAST_MEMBER;
+	adjust_membership(group, join_state, 1);
+	group->rec.join_state |= join_state;
+	member->multicast.rec = group->rec;
+	member->multicast.rec.join_state = join_state;
+	list_move(&member->list, &group->active_list);
+}
+
+static int fail_join(struct mcast_group *group, struct mcast_member *member,
+		     int status)
+{
+	spin_lock_irq(&group->lock);
+	list_del_init(&member->list);
+	spin_unlock_irq(&group->lock);
+	return member->multicast.callback(status, &member->multicast);
+}
+
+static void process_group_error(struct mcast_group *group)
+{
+	struct mcast_member *member;
+	int ret;
+
+	spin_lock_irq(&group->lock);
+	while (!list_empty(&group->active_list)) {
+		member = list_entry(group->active_list.next,
+				    struct mcast_member, list);
+		atomic_inc(&member->refcount);
+		list_del_init(&member->list);
+		adjust_membership(group, member->multicast.rec.join_state, -1);
+		member->state = MCAST_ERROR;
+		spin_unlock_irq(&group->lock);
+
+		ret = member->multicast.callback(-ENETRESET,
+						 &member->multicast);
+		deref_member(member);
+		if (ret)
+			ib_sa_free_multicast(&member->multicast);
+		spin_lock_irq(&group->lock);
+	}
+
+	group->rec.join_state = 0;
+	group->state = MCAST_BUSY;
+	spin_unlock_irq(&group->lock);
+}
+
+static void mcast_work_handler(struct work_struct *work)
+{
+	struct mcast_group *group;
+	struct mcast_member *member;
+	struct ib_sa_multicast *multicast;
+	int status, ret;
+	u8 join_state;
+
+	group = container_of(work, typeof(*group), work);
+retest:
+	spin_lock_irq(&group->lock);
+	while (!list_empty(&group->pending_list) ||
+	       (group->state == MCAST_ERROR)) {
+
+		if (group->state == MCAST_ERROR) {
+			spin_unlock_irq(&group->lock);
+			process_group_error(group);
+			goto retest;
+		}
+
+		member = list_entry(group->pending_list.next,
+				    struct mcast_member, list);
+		multicast = &member->multicast;
+		join_state = multicast->rec.join_state;
+		atomic_inc(&member->refcount);
+
+		if (join_state == (group->rec.join_state & join_state)) {
+			status = cmp_rec(&group->rec, &multicast->rec,
+					 multicast->comp_mask);
+			if (!status)
+				join_group(group, member, join_state);
+			else
+				list_del_init(&member->list);
+			spin_unlock_irq(&group->lock);
+			ret = multicast->callback(status, multicast);
+		} else {
+			spin_unlock_irq(&group->lock);
+			status = send_join(group, member);
+			if (!status) {
+				deref_member(member);
+				return;
+			}
+			ret = fail_join(group, member, status);
+		}
+
+		deref_member(member);
+		if (ret)
+			ib_sa_free_multicast(&member->multicast);
+		spin_lock_irq(&group->lock);
+	}
+
+	join_state = get_leave_state(group);
+	if (join_state) {
+		group->rec.join_state &= ~join_state;
+		spin_unlock_irq(&group->lock);
+		if (send_leave(group, join_state))
+			goto retest;
+	} else {
+		group->state = MCAST_IDLE;
+		spin_unlock_irq(&group->lock);
+		release_group(group);
+	}
+}
+
+/*
+ * Fail a join request if it is still active - at the head of the pending queue.
+ */
+static void process_join_error(struct mcast_group *group, int status)
+{
+	struct mcast_member *member;
+	int ret;
+
+	spin_lock_irq(&group->lock);
+	member = list_entry(group->pending_list.next,
+			    struct mcast_member, list);
+	if (group->last_join == member) {
+		atomic_inc(&member->refcount);
+		list_del_init(&member->list);
+		spin_unlock_irq(&group->lock);
+		ret = member->multicast.callback(status, &member->multicast);
+		deref_member(member);
+		if (ret)
+			ib_sa_free_multicast(&member->multicast);
+	} else
+		spin_unlock_irq(&group->lock);
+}
+
+static void join_handler(int status, struct ib_sa_mcmember_rec *rec,
+			 void *context)
+{
+	struct mcast_group *group = context;
+
+	if (status)
+		process_join_error(group, status);
+	else {
+		spin_lock_irq(&group->port->lock);
+		group->rec = *rec;
+		if (!memcmp(&mgid0, &group->rec.mgid, sizeof mgid0)) {
+			rb_erase(&group->node, &group->port->table);
+			mcast_insert(group->port, group, 1);
+		}
+		spin_unlock_irq(&group->port->lock);
+	}
+	mcast_work_handler(&group->work);
+}
+
+static void leave_handler(int status, struct ib_sa_mcmember_rec *rec,
+			  void *context)
+{
+	struct mcast_group *group = context;
+
+	mcast_work_handler(&group->work);
+}
+
+static struct mcast_group *acquire_group(struct mcast_port *port,
+					 union ib_gid *mgid, gfp_t gfp_mask)
+{
+	struct mcast_group *group, *cur_group;
+	unsigned long flags;
+	int is_mgid0;
+
+	is_mgid0 = !memcmp(&mgid0, mgid, sizeof mgid0);
+	if (!is_mgid0) {
+		spin_lock_irqsave(&port->lock, flags);
+		group = mcast_find(port, mgid);
+		if (group)
+			goto found;
+		spin_unlock_irqrestore(&port->lock, flags);
+	}
+
+	group = kzalloc(sizeof *group, gfp_mask);
+	if (!group)
+		return NULL;
+
+	group->port = port;
+	group->rec.mgid = *mgid;
+	INIT_LIST_HEAD(&group->pending_list);
+	INIT_LIST_HEAD(&group->active_list);
+	INIT_WORK(&group->work, mcast_work_handler);
+	spin_lock_init(&group->lock);
+
+	spin_lock_irqsave(&port->lock, flags);
+	cur_group = mcast_insert(port, group, is_mgid0);
+	if (cur_group) {
+		kfree(group);
+		group = cur_group;
+	} else
+		atomic_inc(&port->refcount);
+found:
+	atomic_inc(&group->refcount);
+	spin_unlock_irqrestore(&port->lock, flags);
+	return group;
+}
+
+/*
+ * We serialize all join requests to a single group to make our lives much
+ * easier.  Otherwise, two users could try to join the same group
+ * simultaneously, with different configurations, one could leave while the
+ * join is in progress, etc., which makes locking around error recovery
+ * difficult.
+ */
+struct ib_sa_multicast *
+ib_sa_join_multicast(struct ib_sa_client *client,
+		     struct ib_device *device, u8 port_num,
+		     struct ib_sa_mcmember_rec *rec,
+		     ib_sa_comp_mask comp_mask, gfp_t gfp_mask,
+		     int (*callback)(int status,
+				     struct ib_sa_multicast *multicast),
+		     void *context)
+{
+	struct mcast_device *dev;
+	struct mcast_member *member;
+	struct ib_sa_multicast *multicast;
+	int ret;
+
+	dev = ib_get_client_data(device, &mcast_client);
+	if (!dev)
+		return ERR_PTR(-ENODEV);
+
+	member = kmalloc(sizeof *member, gfp_mask);
+	if (!member)
+		return ERR_PTR(-ENOMEM);
+
+	ib_sa_client_get(client);
+	member->client = client;
+	member->multicast.rec = *rec;
+	member->multicast.comp_mask = comp_mask;
+	member->multicast.callback = callback;
+	member->multicast.context = context;
+	init_completion(&member->comp);
+	atomic_set(&member->refcount, 1);
+	member->state = MCAST_JOINING;
+
+	member->group = acquire_group(&dev->port[port_num - dev->start_port],
+				      &rec->mgid, gfp_mask);
+	if (!member->group) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	/*
+	 * The user will get the multicast structure in their callback.  They
+	 * could then free the multicast structure before we can return from
+	 * this routine.  So we save the pointer to return before queuing
+	 * any callback.
+	 */
+	multicast = &member->multicast;
+	queue_join(member);
+	return multicast;
+
+err:
+	ib_sa_client_put(client);
+	kfree(member);
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(ib_sa_join_multicast);
+
+void ib_sa_free_multicast(struct ib_sa_multicast *multicast)
+{
+	struct mcast_member *member;
+	struct mcast_group *group;
+
+	member = container_of(multicast, struct mcast_member, multicast);
+	group = member->group;
+
+	spin_lock_irq(&group->lock);
+	if (member->state == MCAST_MEMBER)
+		adjust_membership(group, multicast->rec.join_state, -1);
+
+	list_del_init(&member->list);
+
+	if (group->state == MCAST_IDLE) {
+		group->state = MCAST_BUSY;
+		spin_unlock_irq(&group->lock);
+		/* Continue to hold reference on group until callback */
+		queue_work(mcast_wq, &group->work);
+	} else {
+		spin_unlock_irq(&group->lock);
+		release_group(group);
+	}
+
+	deref_member(member);
+	wait_for_completion(&member->comp);
+	ib_sa_client_put(member->client);
+	kfree(member);
+}
+EXPORT_SYMBOL(ib_sa_free_multicast);
+
+int ib_sa_get_mcmember_rec(struct ib_device *device, u8 port_num,
+			   union ib_gid *mgid, struct ib_sa_mcmember_rec *rec)
+{
+	struct mcast_device *dev;
+	struct mcast_port *port;
+	struct mcast_group *group;
+	unsigned long flags;
+	int ret = 0;
+
+	dev = ib_get_client_data(device, &mcast_client);
+	if (!dev)
+		return -ENODEV;
+
+	port = &dev->port[port_num - dev->start_port];
+	spin_lock_irqsave(&port->lock, flags);
+	group = mcast_find(port, mgid);
+	if (group)
+		*rec = group->rec;
+	else
+		ret = -EADDRNOTAVAIL;
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_sa_get_mcmember_rec);
+
+int ib_init_ah_from_mcmember(struct ib_device *device, u8 port_num,
+			     struct ib_sa_mcmember_rec *rec,
+			     struct ib_ah_attr *ah_attr)
+{
+	int ret;
+	u16 gid_index;
+	u8 p;
+
+	ret = ib_find_cached_gid(device, &rec->port_gid, &p, &gid_index);
+	if (ret)
+		return ret;
+
+	memset(ah_attr, 0, sizeof *ah_attr);
+	ah_attr->dlid = be16_to_cpu(rec->mlid);
+	ah_attr->sl = rec->sl;
+	ah_attr->port_num = port_num;
+	ah_attr->static_rate = rec->rate;
+
+	ah_attr->ah_flags = IB_AH_GRH;
+	ah_attr->grh.dgid = rec->mgid;
+
+	ah_attr->grh.sgid_index = (u8) gid_index;
+	ah_attr->grh.flow_label = be32_to_cpu(rec->flow_label);
+	ah_attr->grh.hop_limit = rec->hop_limit;
+	ah_attr->grh.traffic_class = rec->traffic_class;
+
+	return 0;
+}
+EXPORT_SYMBOL(ib_init_ah_from_mcmember);
+
+static void mcast_groups_lost(struct mcast_port *port)
+{
+	struct mcast_group *group;
+	struct rb_node *node;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	for (node = rb_first(&port->table); node; node = rb_next(node)) {
+		group = rb_entry(node, struct mcast_group, node);
+		spin_lock(&group->lock);
+		if (group->state == MCAST_IDLE) {
+			atomic_inc(&group->refcount);
+			queue_work(mcast_wq, &group->work);
+		}
+		group->state = MCAST_ERROR;
+		spin_unlock(&group->lock);
+	}
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void mcast_event_handler(struct ib_event_handler *handler,
+				struct ib_event *event)
+{
+	struct mcast_device *dev;
+
+	dev = container_of(handler, struct mcast_device, event_handler);
+
+	switch (event->event) {
+	case IB_EVENT_PORT_ERR:
+	case IB_EVENT_LID_CHANGE:
+	case IB_EVENT_SM_CHANGE:
+	case IB_EVENT_CLIENT_REREGISTER:
+		mcast_groups_lost(&dev->port[event->element.port_num -
+					     dev->start_port]);
+		break;
+	default:
+		break;
+	}
+}
+
+static void mcast_add_one(struct ib_device *device)
+{
+	struct mcast_device *dev;
+	struct mcast_port *port;
+	int i;
+
+	if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
+		return;
+
+	dev = kmalloc(sizeof *dev + device->phys_port_cnt * sizeof *port,
+		      GFP_KERNEL);
+	if (!dev)
+		return;
+
+	if (device->node_type == RDMA_NODE_IB_SWITCH)
+		dev->start_port = dev->end_port = 0;
+	else {
+		dev->start_port = 1;
+		dev->end_port = device->phys_port_cnt;
+	}
+
+	for (i = 0; i <= dev->end_port - dev->start_port; i++) {
+		port = &dev->port[i];
+		port->dev = dev;
+		port->port_num = dev->start_port + i;
+		spin_lock_init(&port->lock);
+		port->table = RB_ROOT;
+		init_completion(&port->comp);
+		atomic_set(&port->refcount, 1);
+	}
+
+	dev->device = device;
+	ib_set_client_data(device, &mcast_client, dev);
+
+	INIT_IB_EVENT_HANDLER(&dev->event_handler, device, mcast_event_handler);
+	ib_register_event_handler(&dev->event_handler);
+}
+
+static void mcast_remove_one(struct ib_device *device)
+{
+	struct mcast_device *dev;
+	struct mcast_port *port;
+	int i;
+
+	dev = ib_get_client_data(device, &mcast_client);
+	if (!dev)
+		return;
+
+	ib_unregister_event_handler(&dev->event_handler);
+	flush_workqueue(mcast_wq);
+
+	for (i = 0; i <= dev->end_port - dev->start_port; i++) {
+		port = &dev->port[i];
+		deref_port(port);
+		wait_for_completion(&port->comp);
+	}
+
+	kfree(dev);
+}
+
+int mcast_init(void)
+{
+	int ret;
+
+	mcast_wq = create_singlethread_workqueue("ib_mcast");
+	if (!mcast_wq)
+		return -ENOMEM;
+
+	ib_sa_register_client(&sa_client);
+
+	ret = ib_register_client(&mcast_client);
+	if (ret)
+		goto err;
+	return 0;
+
+err:
+	ib_sa_unregister_client(&sa_client);
+	destroy_workqueue(mcast_wq);
+	return ret;
+}
+
+void mcast_cleanup(void)
+{
+	ib_unregister_client(&mcast_client);
+	ib_sa_unregister_client(&sa_client);
+	destroy_workqueue(mcast_wq);
+}
diff --git a/drivers/infiniband/core/sa.h b/drivers/infiniband/core/sa.h
new file mode 100644
index 0000000..24c93fd
--- /dev/null
+++ b/drivers/infiniband/core/sa.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
+ * Copyright (c) 2006 Intel Corporation.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef SA_H
+#define SA_H
+
+#include <rdma/ib_sa.h>
+
+static inline void ib_sa_client_get(struct ib_sa_client *client)
+{
+	atomic_inc(&client->users);
+}
+
+static inline void ib_sa_client_put(struct ib_sa_client *client)
+{
+	if (atomic_dec_and_test(&client->users))
+		complete(&client->comp);
+}
+
+int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
+			     struct ib_device *device, u8 port_num,
+			     u8 method,
+			     struct ib_sa_mcmember_rec *rec,
+			     ib_sa_comp_mask comp_mask,
+			     int timeout_ms, gfp_t gfp_mask,
+			     void (*callback)(int status,
+					      struct ib_sa_mcmember_rec *resp,
+					      void *context),
+			     void *context,
+			     struct ib_sa_query **sa_query);
+
+int mcast_init(void);
+void mcast_cleanup(void);
+
+#endif /* SA_H */
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index e45afba..68db633 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -47,8 +47,8 @@
 #include <linux/workqueue.h>
 
 #include <rdma/ib_pack.h>
-#include <rdma/ib_sa.h>
 #include <rdma/ib_cache.h>
+#include "sa.h"
 
 MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("InfiniBand subnet administration query support");
@@ -425,17 +425,6 @@
 }
 EXPORT_SYMBOL(ib_sa_register_client);
 
-static inline void ib_sa_client_get(struct ib_sa_client *client)
-{
-	atomic_inc(&client->users);
-}
-
-static inline void ib_sa_client_put(struct ib_sa_client *client)
-{
-	if (atomic_dec_and_test(&client->users))
-		complete(&client->comp);
-}
-
 void ib_sa_unregister_client(struct ib_sa_client *client)
 {
 	ib_sa_client_put(client);
@@ -482,6 +471,7 @@
 	ah_attr->sl = rec->sl;
 	ah_attr->src_path_bits = be16_to_cpu(rec->slid) & 0x7f;
 	ah_attr->port_num = port_num;
+	ah_attr->static_rate = rec->rate;
 
 	if (rec->hop_limit > 1) {
 		ah_attr->ah_flags = IB_AH_GRH;
@@ -901,7 +891,6 @@
 	kfree(query);
 	return ret;
 }
-EXPORT_SYMBOL(ib_sa_mcmember_rec_query);
 
 static void send_handler(struct ib_mad_agent *agent,
 			 struct ib_mad_send_wc *mad_send_wc)
@@ -1053,14 +1042,27 @@
 	get_random_bytes(&tid, sizeof tid);
 
 	ret = ib_register_client(&sa_client);
-	if (ret)
+	if (ret) {
 		printk(KERN_ERR "Couldn't register ib_sa client\n");
+		goto err1;
+	}
 
+	ret = mcast_init();
+	if (ret) {
+		printk(KERN_ERR "Couldn't initialize multicast handling\n");
+		goto err2;
+	}
+
+	return 0;
+err2:
+	ib_unregister_client(&sa_client);
+err1:
 	return ret;
 }
 
 static void __exit ib_sa_cleanup(void)
 {
+	mcast_cleanup();
 	ib_unregister_client(&sa_client);
 	idr_destroy(&query_idr);
 }
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 709323c..000c086 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -714,8 +714,6 @@
 		if (ret)
 			goto err_put;
 	} else {
-		int i;
-
 		for (i = 1; i <= device->phys_port_cnt; ++i) {
 			ret = add_port(device, i);
 			if (ret)
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 6b81b98..b516b93 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -70,10 +70,24 @@
 	u64			uid;
 
 	struct list_head	list;
+	struct list_head	mc_list;
+};
+
+struct ucma_multicast {
+	struct ucma_context	*ctx;
+	int			id;
+	int			events_reported;
+
+	u64			uid;
+	struct list_head	list;
+	struct sockaddr		addr;
+	u8			pad[sizeof(struct sockaddr_in6) -
+				    sizeof(struct sockaddr)];
 };
 
 struct ucma_event {
 	struct ucma_context	*ctx;
+	struct ucma_multicast	*mc;
 	struct list_head	list;
 	struct rdma_cm_id	*cm_id;
 	struct rdma_ucm_event_resp resp;
@@ -81,6 +95,7 @@
 
 static DEFINE_MUTEX(mut);
 static DEFINE_IDR(ctx_idr);
+static DEFINE_IDR(multicast_idr);
 
 static inline struct ucma_context *_ucma_find_context(int id,
 						      struct ucma_file *file)
@@ -124,6 +139,7 @@
 
 	atomic_set(&ctx->ref, 1);
 	init_completion(&ctx->comp);
+	INIT_LIST_HEAD(&ctx->mc_list);
 	ctx->file = file;
 
 	do {
@@ -147,6 +163,37 @@
 	return NULL;
 }
 
+static struct ucma_multicast* ucma_alloc_multicast(struct ucma_context *ctx)
+{
+	struct ucma_multicast *mc;
+	int ret;
+
+	mc = kzalloc(sizeof(*mc), GFP_KERNEL);
+	if (!mc)
+		return NULL;
+
+	do {
+		ret = idr_pre_get(&multicast_idr, GFP_KERNEL);
+		if (!ret)
+			goto error;
+
+		mutex_lock(&mut);
+		ret = idr_get_new(&multicast_idr, mc, &mc->id);
+		mutex_unlock(&mut);
+	} while (ret == -EAGAIN);
+
+	if (ret)
+		goto error;
+
+	mc->ctx = ctx;
+	list_add_tail(&mc->list, &ctx->mc_list);
+	return mc;
+
+error:
+	kfree(mc);
+	return NULL;
+}
+
 static void ucma_copy_conn_event(struct rdma_ucm_conn_param *dst,
 				 struct rdma_conn_param *src)
 {
@@ -180,8 +227,19 @@
 				   struct ucma_event *uevent)
 {
 	uevent->ctx = ctx;
-	uevent->resp.uid = ctx->uid;
-	uevent->resp.id = ctx->id;
+	switch (event->event) {
+	case RDMA_CM_EVENT_MULTICAST_JOIN:
+	case RDMA_CM_EVENT_MULTICAST_ERROR:
+		uevent->mc = (struct ucma_multicast *)
+			     event->param.ud.private_data;
+		uevent->resp.uid = uevent->mc->uid;
+		uevent->resp.id = uevent->mc->id;
+		break;
+	default:
+		uevent->resp.uid = ctx->uid;
+		uevent->resp.id = ctx->id;
+		break;
+	}
 }
 
 static int ucma_event_handler(struct rdma_cm_id *cm_id,
@@ -199,7 +257,7 @@
 	ucma_set_event_context(ctx, event, uevent);
 	uevent->resp.event = event->event;
 	uevent->resp.status = event->status;
-	if (cm_id->ps == RDMA_PS_UDP)
+	if (cm_id->ps == RDMA_PS_UDP || cm_id->ps == RDMA_PS_IPOIB)
 		ucma_copy_ud_event(&uevent->resp.param.ud, &event->param.ud);
 	else
 		ucma_copy_conn_event(&uevent->resp.param.conn,
@@ -290,6 +348,8 @@
 
 	list_del(&uevent->list);
 	uevent->ctx->events_reported++;
+	if (uevent->mc)
+		uevent->mc->events_reported++;
 	kfree(uevent);
 done:
 	mutex_unlock(&file->mut);
@@ -342,6 +402,19 @@
 	return ret;
 }
 
+static void ucma_cleanup_multicast(struct ucma_context *ctx)
+{
+	struct ucma_multicast *mc, *tmp;
+
+	mutex_lock(&mut);
+	list_for_each_entry_safe(mc, tmp, &ctx->mc_list, list) {
+		list_del(&mc->list);
+		idr_remove(&multicast_idr, mc->id);
+		kfree(mc);
+	}
+	mutex_unlock(&mut);
+}
+
 static void ucma_cleanup_events(struct ucma_context *ctx)
 {
 	struct ucma_event *uevent, *tmp;
@@ -360,6 +433,19 @@
 	}
 }
 
+static void ucma_cleanup_mc_events(struct ucma_multicast *mc)
+{
+	struct ucma_event *uevent, *tmp;
+
+	list_for_each_entry_safe(uevent, tmp, &mc->ctx->file->event_list, list) {
+		if (uevent->mc != mc)
+			continue;
+
+		list_del(&uevent->list);
+		kfree(uevent);
+	}
+}
+
 static int ucma_free_ctx(struct ucma_context *ctx)
 {
 	int events_reported;
@@ -367,6 +453,8 @@
 	/* No new events will be generated after destroying the id. */
 	rdma_destroy_id(ctx->cm_id);
 
+	ucma_cleanup_multicast(ctx);
+
 	/* Cleanup events not yet reported to the user. */
 	mutex_lock(&ctx->file->mut);
 	ucma_cleanup_events(ctx);
@@ -731,6 +819,114 @@
 	return ret;
 }
 
+static ssize_t ucma_join_multicast(struct ucma_file *file,
+				   const char __user *inbuf,
+				   int in_len, int out_len)
+{
+	struct rdma_ucm_join_mcast cmd;
+	struct rdma_ucm_create_id_resp resp;
+	struct ucma_context *ctx;
+	struct ucma_multicast *mc;
+	int ret;
+
+	if (out_len < sizeof(resp))
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	ctx = ucma_get_ctx(file, cmd.id);
+	if (IS_ERR(ctx))
+		return PTR_ERR(ctx);
+
+	mutex_lock(&file->mut);
+	mc = ucma_alloc_multicast(ctx);
+	if (IS_ERR(mc)) {
+		ret = PTR_ERR(mc);
+		goto err1;
+	}
+
+	mc->uid = cmd.uid;
+	memcpy(&mc->addr, &cmd.addr, sizeof cmd.addr);
+	ret = rdma_join_multicast(ctx->cm_id, &mc->addr, mc);
+	if (ret)
+		goto err2;
+
+	resp.id = mc->id;
+	if (copy_to_user((void __user *)(unsigned long)cmd.response,
+			 &resp, sizeof(resp))) {
+		ret = -EFAULT;
+		goto err3;
+	}
+
+	mutex_unlock(&file->mut);
+	ucma_put_ctx(ctx);
+	return 0;
+
+err3:
+	rdma_leave_multicast(ctx->cm_id, &mc->addr);
+	ucma_cleanup_mc_events(mc);
+err2:
+	mutex_lock(&mut);
+	idr_remove(&multicast_idr, mc->id);
+	mutex_unlock(&mut);
+	list_del(&mc->list);
+	kfree(mc);
+err1:
+	mutex_unlock(&file->mut);
+	ucma_put_ctx(ctx);
+	return ret;
+}
+
+static ssize_t ucma_leave_multicast(struct ucma_file *file,
+				    const char __user *inbuf,
+				    int in_len, int out_len)
+{
+	struct rdma_ucm_destroy_id cmd;
+	struct rdma_ucm_destroy_id_resp resp;
+	struct ucma_multicast *mc;
+	int ret = 0;
+
+	if (out_len < sizeof(resp))
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	mutex_lock(&mut);
+	mc = idr_find(&multicast_idr, cmd.id);
+	if (!mc)
+		mc = ERR_PTR(-ENOENT);
+	else if (mc->ctx->file != file)
+		mc = ERR_PTR(-EINVAL);
+	else {
+		idr_remove(&multicast_idr, mc->id);
+		atomic_inc(&mc->ctx->ref);
+	}
+	mutex_unlock(&mut);
+
+	if (IS_ERR(mc)) {
+		ret = PTR_ERR(mc);
+		goto out;
+	}
+
+	rdma_leave_multicast(mc->ctx->cm_id, &mc->addr);
+	mutex_lock(&mc->ctx->file->mut);
+	ucma_cleanup_mc_events(mc);
+	list_del(&mc->list);
+	mutex_unlock(&mc->ctx->file->mut);
+
+	ucma_put_ctx(mc->ctx);
+	resp.events_reported = mc->events_reported;
+	kfree(mc);
+
+	if (copy_to_user((void __user *)(unsigned long)cmd.response,
+			 &resp, sizeof(resp)))
+		ret = -EFAULT;
+out:
+	return ret;
+}
+
 static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
 				   const char __user *inbuf,
 				   int in_len, int out_len) = {
@@ -750,6 +946,8 @@
 	[RDMA_USER_CM_CMD_GET_OPTION]	= NULL,
 	[RDMA_USER_CM_CMD_SET_OPTION]	= NULL,
 	[RDMA_USER_CM_CMD_NOTIFY]	= ucma_notify,
+	[RDMA_USER_CM_CMD_JOIN_MCAST]	= ucma_join_multicast,
+	[RDMA_USER_CM_CMD_LEAVE_MCAST]	= ucma_leave_multicast,
 };
 
 static ssize_t ucma_write(struct file *filp, const char __user *buf,
diff --git a/drivers/infiniband/hw/cxgb3/cxio_dbg.c b/drivers/infiniband/hw/cxgb3/cxio_dbg.c
index 5a7306f..75f7b16 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_dbg.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_dbg.c
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index 82fa720..114ac3b 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h
index 1b97e80..8ab04a7 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.c b/drivers/infiniband/hw/cxgb3/cxio_resource.c
index 997aa32..65bf577 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_resource.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_resource.c
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.h b/drivers/infiniband/hw/cxgb3/cxio_resource.h
index a6bbe83..a2703a3 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_resource.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_resource.h
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h
index 103fc42..90d7b89 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_wr.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c
index 4611afa..0315c9d 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.c
+++ b/drivers/infiniband/hw/cxgb3/iwch.c
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch.h b/drivers/infiniband/hw/cxgb3/iwch.h
index 6517ef8..caf4e60 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.h
+++ b/drivers/infiniband/hw/cxgb3/iwch.h
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index a522b1b..e5442e3 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.h b/drivers/infiniband/hw/cxgb3/iwch_cm.h
index 7c810d9..0c6f281 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.h
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.h
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cq.c b/drivers/infiniband/hw/cxgb3/iwch_cq.c
index 98b3bdb..d7624c1 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cq.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cq.c
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_ev.c b/drivers/infiniband/hw/cxgb3/iwch_ev.c
index a6efa8fe..54362af 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_ev.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_ev.c
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_mem.c b/drivers/infiniband/hw/cxgb3/iwch_mem.c
index 2b6cd53..a6c2c4b 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_mem.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_mem.c
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index 6861087..2aef122 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.h b/drivers/infiniband/hw/cxgb3/iwch_provider.h
index 61e3278..2af3e93 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.h
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.h
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c
index e066727..4dda2f6 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_qp.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -846,6 +845,8 @@
 			break;
 		case IWCH_QP_STATE_TERMINATE:
 			qhp->attr.state = IWCH_QP_STATE_TERMINATE;
+			if (t3b_device(qhp->rhp))
+				cxio_set_wq_in_error(&qhp->wq);
 			if (!internal)
 				terminate = 1;
 			break;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_user.h b/drivers/infiniband/hw/cxgb3/iwch_user.h
index c4e7fbe..cb7086f 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_user.h
+++ b/drivers/infiniband/hw/cxgb3/iwch_user.h
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/ehca/Kconfig b/drivers/infiniband/hw/ehca/Kconfig
index 727b10d..1a85459 100644
--- a/drivers/infiniband/hw/ehca/Kconfig
+++ b/drivers/infiniband/hw/ehca/Kconfig
@@ -7,11 +7,3 @@
 	To compile the driver as a module, choose M here. The module
 	will be called ib_ehca.
 
-config INFINIBAND_EHCA_SCALING
-	bool "Scaling support (EXPERIMENTAL)"
-	depends on IBMEBUS && INFINIBAND_EHCA && HOTPLUG_CPU && EXPERIMENTAL
-	default y
-	---help---
-	eHCA scaling support schedules the CQ callbacks to different CPUs.
-
-	To enable this feature choose Y here.
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index cf95ee4..40404c9 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -42,8 +42,6 @@
 #ifndef __EHCA_CLASSES_H__
 #define __EHCA_CLASSES_H__
 
-#include "ehca_classes.h"
-#include "ipz_pt_fn.h"
 
 struct ehca_module;
 struct ehca_qp;
@@ -54,15 +52,23 @@
 struct ehca_pd;
 struct ehca_av;
 
-#ifdef CONFIG_PPC64
-#include "ehca_classes_pSeries.h"
-#endif
-
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_user_verbs.h>
 
+#ifdef CONFIG_PPC64
+#include "ehca_classes_pSeries.h"
+#endif
+#include "ipz_pt_fn.h"
+#include "ehca_qes.h"
 #include "ehca_irq.h"
 
+#define EHCA_EQE_CACHE_SIZE 20
+
+struct ehca_eqe_cache_entry {
+	struct ehca_eqe *eqe;
+	struct ehca_cq *cq;
+};
+
 struct ehca_eq {
 	u32 length;
 	struct ipz_queue ipz_queue;
@@ -74,6 +80,8 @@
 	spinlock_t spinlock;
 	struct tasklet_struct interrupt_task;
 	u32 ist;
+	spinlock_t irq_spinlock;
+	struct ehca_eqe_cache_entry eqe_cache[EHCA_EQE_CACHE_SIZE];
 };
 
 struct ehca_sport {
@@ -269,6 +277,7 @@
 extern int ehca_static_rate;
 extern int ehca_port_act_time;
 extern int ehca_use_hp_mr;
+extern int ehca_scaling_code;
 
 struct ipzu_queue_resp {
 	u32 qe_size;      /* queue entry size */
diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c
index 24ceab0..4961eb8 100644
--- a/drivers/infiniband/hw/ehca/ehca_eq.c
+++ b/drivers/infiniband/hw/ehca/ehca_eq.c
@@ -61,6 +61,7 @@
 	struct ib_device *ib_dev = &shca->ib_device;
 
 	spin_lock_init(&eq->spinlock);
+	spin_lock_init(&eq->irq_spinlock);
 	eq->is_initialized = 0;
 
 	if (type != EHCA_EQ && type != EHCA_NEQ) {
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
index b7be950..30eb45d 100644
--- a/drivers/infiniband/hw/ehca/ehca_hca.c
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c
@@ -162,6 +162,9 @@
 	props->active_width    = IB_WIDTH_12X;
 	props->active_speed    = 0x1;
 
+	/* at the moment (logical) link state is always LINK_UP */
+	props->phys_state      = 0x5;
+
 query_port1:
 	ehca_free_fw_ctrlblock(rblock);
 
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index 6c4f9f9..3ec53c6 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -63,15 +63,11 @@
 #define ERROR_DATA_LENGTH      EHCA_BMASK_IBM(52,63)
 #define ERROR_DATA_TYPE        EHCA_BMASK_IBM(0,7)
 
-#ifdef CONFIG_INFINIBAND_EHCA_SCALING
-
 static void queue_comp_task(struct ehca_cq *__cq);
 
 static struct ehca_comp_pool* pool;
 static struct notifier_block comp_pool_callback_nb;
 
-#endif
-
 static inline void comp_event_callback(struct ehca_cq *cq)
 {
 	if (!cq->ib_cq.comp_handler)
@@ -206,7 +202,7 @@
 }
 
 static void cq_event_callback(struct ehca_shca *shca,
-					  u64 eqe)
+			      u64 eqe)
 {
 	struct ehca_cq *cq;
 	unsigned long flags;
@@ -318,7 +314,7 @@
 			  "disruptive port %x configuration change", port);
 
 		ehca_info(&shca->ib_device,
-			 "port %x is inactive.", port);
+			  "port %x is inactive.", port);
 		event.device = &shca->ib_device;
 		event.event = IB_EVENT_PORT_ERR;
 		event.element.port_num = port;
@@ -326,7 +322,7 @@
 		ib_dispatch_event(&event);
 
 		ehca_info(&shca->ib_device,
-			 "port %x is active.", port);
+			  "port %x is active.", port);
 		event.device = &shca->ib_device;
 		event.event = IB_EVENT_PORT_ACTIVE;
 		event.element.port_num = port;
@@ -401,115 +397,170 @@
 	return IRQ_HANDLED;
 }
 
-void ehca_tasklet_eq(unsigned long data)
+
+static inline void process_eqe(struct ehca_shca *shca, struct ehca_eqe *eqe)
 {
-	struct ehca_shca *shca = (struct ehca_shca*)data;
-	struct ehca_eqe *eqe;
-	int int_state;
-	int query_cnt = 0;
-
-	do {
-		eqe = (struct ehca_eqe *)ehca_poll_eq(shca, &shca->eq);
-
-		if ((shca->hw_level >= 2) && eqe)
-			int_state = 1;
-		else
-			int_state = 0;
-
-		while ((int_state == 1) || eqe) {
-			while (eqe) {
-				u64 eqe_value = eqe->entry;
-
-				ehca_dbg(&shca->ib_device,
-					 "eqe_value=%lx", eqe_value);
-
-				/* TODO: better structure */
-				if (EHCA_BMASK_GET(EQE_COMPLETION_EVENT,
-						   eqe_value)) {
-					unsigned long flags;
-					u32 token;
-					struct ehca_cq *cq;
-
-					ehca_dbg(&shca->ib_device,
-						 "... completion event");
-					token =
-						EHCA_BMASK_GET(EQE_CQ_TOKEN,
-							       eqe_value);
-					spin_lock_irqsave(&ehca_cq_idr_lock,
-							  flags);
-					cq = idr_find(&ehca_cq_idr, token);
-
-					if (cq == NULL) {
-						spin_unlock_irqrestore(&ehca_cq_idr_lock,
-								       flags);
-						break;
-					}
-
-					reset_eq_pending(cq);
-#ifdef CONFIG_INFINIBAND_EHCA_SCALING
-					queue_comp_task(cq);
-					spin_unlock_irqrestore(&ehca_cq_idr_lock,
-							       flags);
-#else
-					spin_unlock_irqrestore(&ehca_cq_idr_lock,
-							       flags);
-					comp_event_callback(cq);
-#endif
-				} else {
-					ehca_dbg(&shca->ib_device,
-						 "... non completion event");
-					parse_identifier(shca, eqe_value);
-				}
-				eqe =
-					(struct ehca_eqe *)ehca_poll_eq(shca,
-								    &shca->eq);
-			}
-
-			if (shca->hw_level >= 2) {
-				int_state =
-				    hipz_h_query_int_state(shca->ipz_hca_handle,
-							   shca->eq.ist);
-				query_cnt++;
-				iosync();
-				if (query_cnt >= 100) {
-					query_cnt = 0;
-					int_state = 0;
-				}
-			}
-			eqe = (struct ehca_eqe *)ehca_poll_eq(shca, &shca->eq);
-
+	u64 eqe_value;
+	u32 token;
+	unsigned long flags;
+	struct ehca_cq *cq;
+	eqe_value = eqe->entry;
+	ehca_dbg(&shca->ib_device, "eqe_value=%lx", eqe_value);
+	if (EHCA_BMASK_GET(EQE_COMPLETION_EVENT, eqe_value)) {
+		ehca_dbg(&shca->ib_device, "... completion event");
+		token = EHCA_BMASK_GET(EQE_CQ_TOKEN, eqe_value);
+		spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+		cq = idr_find(&ehca_cq_idr, token);
+		if (cq == NULL) {
+			spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+			ehca_err(&shca->ib_device,
+				 "Invalid eqe for non-existing cq token=%x",
+				 token);
+			return;
 		}
-	} while (int_state != 0);
-
-	return;
+		reset_eq_pending(cq);
+		if (ehca_scaling_code) {
+			queue_comp_task(cq);
+			spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+		} else {
+			spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+			comp_event_callback(cq);
+		}
+	} else {
+		ehca_dbg(&shca->ib_device,
+			 "Got non completion event");
+		parse_identifier(shca, eqe_value);
+	}
 }
 
-#ifdef CONFIG_INFINIBAND_EHCA_SCALING
+void ehca_process_eq(struct ehca_shca *shca, int is_irq)
+{
+	struct ehca_eq *eq = &shca->eq;
+	struct ehca_eqe_cache_entry *eqe_cache = eq->eqe_cache;
+	u64 eqe_value;
+	unsigned long flags;
+	int eqe_cnt, i;
+	int eq_empty = 0;
+
+	spin_lock_irqsave(&eq->irq_spinlock, flags);
+	if (is_irq) {
+		const int max_query_cnt = 100;
+		int query_cnt = 0;
+		int int_state = 1;
+		do {
+			int_state = hipz_h_query_int_state(
+				shca->ipz_hca_handle, eq->ist);
+			query_cnt++;
+			iosync();
+		} while (int_state && query_cnt < max_query_cnt);
+		if (unlikely((query_cnt == max_query_cnt)))
+			ehca_dbg(&shca->ib_device, "int_state=%x query_cnt=%x",
+				 int_state, query_cnt);
+	}
+
+	/* read out all eqes */
+	eqe_cnt = 0;
+	do {
+		u32 token;
+		eqe_cache[eqe_cnt].eqe =
+			(struct ehca_eqe *)ehca_poll_eq(shca, eq);
+		if (!eqe_cache[eqe_cnt].eqe)
+			break;
+		eqe_value = eqe_cache[eqe_cnt].eqe->entry;
+		if (EHCA_BMASK_GET(EQE_COMPLETION_EVENT, eqe_value)) {
+			token = EHCA_BMASK_GET(EQE_CQ_TOKEN, eqe_value);
+			spin_lock(&ehca_cq_idr_lock);
+			eqe_cache[eqe_cnt].cq = idr_find(&ehca_cq_idr, token);
+			if (!eqe_cache[eqe_cnt].cq) {
+				spin_unlock(&ehca_cq_idr_lock);
+				ehca_err(&shca->ib_device,
+					 "Invalid eqe for non-existing cq "
+					 "token=%x", token);
+				continue;
+			}
+			spin_unlock(&ehca_cq_idr_lock);
+		} else
+			eqe_cache[eqe_cnt].cq = NULL;
+		eqe_cnt++;
+	} while (eqe_cnt < EHCA_EQE_CACHE_SIZE);
+	if (!eqe_cnt) {
+		if (is_irq)
+			ehca_dbg(&shca->ib_device,
+				 "No eqe found for irq event");
+		goto unlock_irq_spinlock;
+	} else if (!is_irq)
+		ehca_dbg(&shca->ib_device, "deadman found %x eqe", eqe_cnt);
+	if (unlikely(eqe_cnt == EHCA_EQE_CACHE_SIZE))
+		ehca_dbg(&shca->ib_device, "too many eqes for one irq event");
+	/* enable irq for new packets */
+	for (i = 0; i < eqe_cnt; i++) {
+		if (eq->eqe_cache[i].cq)
+			reset_eq_pending(eq->eqe_cache[i].cq);
+	}
+	/* check eq */
+	spin_lock(&eq->spinlock);
+	eq_empty = (!ipz_eqit_eq_peek_valid(&shca->eq.ipz_queue));
+	spin_unlock(&eq->spinlock);
+	/* call completion handler for cached eqes */
+	for (i = 0; i < eqe_cnt; i++)
+		if (eq->eqe_cache[i].cq) {
+			if (ehca_scaling_code) {
+				spin_lock(&ehca_cq_idr_lock);
+				queue_comp_task(eq->eqe_cache[i].cq);
+				spin_unlock(&ehca_cq_idr_lock);
+			} else
+				comp_event_callback(eq->eqe_cache[i].cq);
+		} else {
+			ehca_dbg(&shca->ib_device, "Got non completion event");
+			parse_identifier(shca, eq->eqe_cache[i].eqe->entry);
+		}
+	/* poll eq if not empty */
+	if (eq_empty)
+		goto unlock_irq_spinlock;
+	do {
+		struct ehca_eqe *eqe;
+		eqe = (struct ehca_eqe *)ehca_poll_eq(shca, &shca->eq);
+		if (!eqe)
+			break;
+		process_eqe(shca, eqe);
+		eqe_cnt++;
+	} while (1);
+
+unlock_irq_spinlock:
+	spin_unlock_irqrestore(&eq->irq_spinlock, flags);
+}
+
+void ehca_tasklet_eq(unsigned long data)
+{
+	ehca_process_eq((struct ehca_shca*)data, 1);
+}
 
 static inline int find_next_online_cpu(struct ehca_comp_pool* pool)
 {
-	unsigned long flags_last_cpu;
+	int cpu;
+	unsigned long flags;
 
+	WARN_ON_ONCE(!in_interrupt());
 	if (ehca_debug_level)
 		ehca_dmp(&cpu_online_map, sizeof(cpumask_t), "");
 
-	spin_lock_irqsave(&pool->last_cpu_lock, flags_last_cpu);
-	pool->last_cpu = next_cpu(pool->last_cpu, cpu_online_map);
-	if (pool->last_cpu == NR_CPUS)
-		pool->last_cpu = first_cpu(cpu_online_map);
-	spin_unlock_irqrestore(&pool->last_cpu_lock, flags_last_cpu);
+	spin_lock_irqsave(&pool->last_cpu_lock, flags);
+	cpu = next_cpu(pool->last_cpu, cpu_online_map);
+	if (cpu == NR_CPUS)
+		cpu = first_cpu(cpu_online_map);
+	pool->last_cpu = cpu;
+	spin_unlock_irqrestore(&pool->last_cpu_lock, flags);
 
-	return pool->last_cpu;
+	return cpu;
 }
 
 static void __queue_comp_task(struct ehca_cq *__cq,
 			      struct ehca_cpu_comp_task *cct)
 {
-	unsigned long flags_cct;
-	unsigned long flags_cq;
+	unsigned long flags;
 
-	spin_lock_irqsave(&cct->task_lock, flags_cct);
-	spin_lock_irqsave(&__cq->task_lock, flags_cq);
+	spin_lock_irqsave(&cct->task_lock, flags);
+	spin_lock(&__cq->task_lock);
 
 	if (__cq->nr_callbacks == 0) {
 		__cq->nr_callbacks++;
@@ -520,8 +571,8 @@
 	else
 		__cq->nr_callbacks++;
 
-	spin_unlock_irqrestore(&__cq->task_lock, flags_cq);
-	spin_unlock_irqrestore(&cct->task_lock, flags_cct);
+	spin_unlock(&__cq->task_lock);
+	spin_unlock_irqrestore(&cct->task_lock, flags);
 }
 
 static void queue_comp_task(struct ehca_cq *__cq)
@@ -532,69 +583,69 @@
 
 	cpu = get_cpu();
 	cpu_id = find_next_online_cpu(pool);
-
 	BUG_ON(!cpu_online(cpu_id));
 
 	cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id);
+	BUG_ON(!cct);
 
 	if (cct->cq_jobs > 0) {
 		cpu_id = find_next_online_cpu(pool);
 		cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id);
+		BUG_ON(!cct);
 	}
 
 	__queue_comp_task(__cq, cct);
-
-	put_cpu();
-
-	return;
 }
 
 static void run_comp_task(struct ehca_cpu_comp_task* cct)
 {
 	struct ehca_cq *cq;
-	unsigned long flags_cct;
-	unsigned long flags_cq;
+	unsigned long flags;
 
-	spin_lock_irqsave(&cct->task_lock, flags_cct);
+	spin_lock_irqsave(&cct->task_lock, flags);
 
 	while (!list_empty(&cct->cq_list)) {
 		cq = list_entry(cct->cq_list.next, struct ehca_cq, entry);
-		spin_unlock_irqrestore(&cct->task_lock, flags_cct);
+		spin_unlock_irqrestore(&cct->task_lock, flags);
 		comp_event_callback(cq);
-		spin_lock_irqsave(&cct->task_lock, flags_cct);
+		spin_lock_irqsave(&cct->task_lock, flags);
 
-		spin_lock_irqsave(&cq->task_lock, flags_cq);
+		spin_lock(&cq->task_lock);
 		cq->nr_callbacks--;
 		if (cq->nr_callbacks == 0) {
 			list_del_init(cct->cq_list.next);
 			cct->cq_jobs--;
 		}
-		spin_unlock_irqrestore(&cq->task_lock, flags_cq);
-
+		spin_unlock(&cq->task_lock);
 	}
 
-	spin_unlock_irqrestore(&cct->task_lock, flags_cct);
-
-	return;
+	spin_unlock_irqrestore(&cct->task_lock, flags);
 }
 
 static int comp_task(void *__cct)
 {
 	struct ehca_cpu_comp_task* cct = __cct;
+	int cql_empty;
 	DECLARE_WAITQUEUE(wait, current);
 
 	set_current_state(TASK_INTERRUPTIBLE);
 	while(!kthread_should_stop()) {
 		add_wait_queue(&cct->wait_queue, &wait);
 
-		if (list_empty(&cct->cq_list))
+		spin_lock_irq(&cct->task_lock);
+		cql_empty = list_empty(&cct->cq_list);
+		spin_unlock_irq(&cct->task_lock);
+		if (cql_empty)
 			schedule();
 		else
 			__set_current_state(TASK_RUNNING);
 
 		remove_wait_queue(&cct->wait_queue, &wait);
 
-		if (!list_empty(&cct->cq_list))
+		spin_lock_irq(&cct->task_lock);
+		cql_empty = list_empty(&cct->cq_list);
+		spin_unlock_irq(&cct->task_lock);
+		if (!cql_empty)
 			run_comp_task(__cct);
 
 		set_current_state(TASK_INTERRUPTIBLE);
@@ -637,8 +688,6 @@
 
 	if (task)
 		kthread_stop(task);
-
-	return;
 }
 
 static void take_over_work(struct ehca_comp_pool *pool,
@@ -654,11 +703,11 @@
 	list_splice_init(&cct->cq_list, &list);
 
 	while(!list_empty(&list)) {
-	       cq = list_entry(cct->cq_list.next, struct ehca_cq, entry);
+		cq = list_entry(cct->cq_list.next, struct ehca_cq, entry);
 
-	       list_del(&cq->entry);
-	       __queue_comp_task(cq, per_cpu_ptr(pool->cpu_comp_tasks,
-						 smp_processor_id()));
+		list_del(&cq->entry);
+		__queue_comp_task(cq, per_cpu_ptr(pool->cpu_comp_tasks,
+						  smp_processor_id()));
 	}
 
 	spin_unlock_irqrestore(&cct->task_lock, flags_cct);
@@ -708,14 +757,14 @@
 	return NOTIFY_OK;
 }
 
-#endif
-
 int ehca_create_comp_pool(void)
 {
-#ifdef CONFIG_INFINIBAND_EHCA_SCALING
 	int cpu;
 	struct task_struct *task;
 
+	if (!ehca_scaling_code)
+		return 0;
+
 	pool = kzalloc(sizeof(struct ehca_comp_pool), GFP_KERNEL);
 	if (pool == NULL)
 		return -ENOMEM;
@@ -740,16 +789,19 @@
 	comp_pool_callback_nb.notifier_call = comp_pool_callback;
 	comp_pool_callback_nb.priority =0;
 	register_cpu_notifier(&comp_pool_callback_nb);
-#endif
+
+	printk(KERN_INFO "eHCA scaling code enabled\n");
 
 	return 0;
 }
 
 void ehca_destroy_comp_pool(void)
 {
-#ifdef CONFIG_INFINIBAND_EHCA_SCALING
 	int i;
 
+	if (!ehca_scaling_code)
+		return;
+
 	unregister_cpu_notifier(&comp_pool_callback_nb);
 
 	for (i = 0; i < NR_CPUS; i++) {
@@ -758,7 +810,4 @@
 	}
 	free_percpu(pool->cpu_comp_tasks);
 	kfree(pool);
-#endif
-
-	return;
 }
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.h b/drivers/infiniband/hw/ehca/ehca_irq.h
index be579cc..6ed06ee 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.h
+++ b/drivers/infiniband/hw/ehca/ehca_irq.h
@@ -56,6 +56,7 @@
 
 irqreturn_t ehca_interrupt_eq(int irq, void *dev_id);
 void ehca_tasklet_eq(unsigned long data);
+void ehca_process_eq(struct ehca_shca *shca, int is_irq);
 
 struct ehca_cpu_comp_task {
 	wait_queue_head_t wait_queue;
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 1155bcf..c183512 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -52,7 +52,7 @@
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
 MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
-MODULE_VERSION("SVNEHCA_0020");
+MODULE_VERSION("SVNEHCA_0021");
 
 int ehca_open_aqp1     = 0;
 int ehca_debug_level   = 0;
@@ -62,6 +62,7 @@
 int ehca_port_act_time = 30;
 int ehca_poll_all_eqs  = 1;
 int ehca_static_rate   = -1;
+int ehca_scaling_code  = 1;
 
 module_param_named(open_aqp1,     ehca_open_aqp1,     int, 0);
 module_param_named(debug_level,   ehca_debug_level,   int, 0);
@@ -71,6 +72,7 @@
 module_param_named(port_act_time, ehca_port_act_time, int, 0);
 module_param_named(poll_all_eqs,  ehca_poll_all_eqs,  int, 0);
 module_param_named(static_rate,   ehca_static_rate,   int, 0);
+module_param_named(scaling_code,   ehca_scaling_code,   int, 0);
 
 MODULE_PARM_DESC(open_aqp1,
 		 "AQP1 on startup (0: no (default), 1: yes)");
@@ -91,6 +93,8 @@
 		 " (0: no, 1: yes (default))");
 MODULE_PARM_DESC(static_rate,
 		 "set permanent static rate (default: disabled)");
+MODULE_PARM_DESC(scaling_code,
+		 "set scaling code (0: disabled, 1: enabled/default)");
 
 spinlock_t ehca_qp_idr_lock;
 spinlock_t ehca_cq_idr_lock;
@@ -432,8 +436,8 @@
 
 static ssize_t ehca_show_debug_level(struct device_driver *ddp, char *buf)
 {
-	return  snprintf(buf, PAGE_SIZE, "%d\n",
-			 ehca_debug_level);
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+			ehca_debug_level);
 }
 
 static ssize_t ehca_store_debug_level(struct device_driver *ddp,
@@ -778,8 +782,24 @@
 
 	spin_lock(&shca_list_lock);
 	list_for_each_entry(shca, &shca_list, shca_list) {
-		if (shca->eq.is_initialized)
-			ehca_tasklet_eq((unsigned long)(void*)shca);
+		if (shca->eq.is_initialized) {
+			/* call deadman proc only if eq ptr does not change */
+			struct ehca_eq *eq = &shca->eq;
+			int max = 3;
+			volatile u64 q_ofs, q_ofs2;
+			u64 flags;
+			spin_lock_irqsave(&eq->spinlock, flags);
+			q_ofs = eq->ipz_queue.current_q_offset;
+			spin_unlock_irqrestore(&eq->spinlock, flags);
+			do {
+				spin_lock_irqsave(&eq->spinlock, flags);
+				q_ofs2 = eq->ipz_queue.current_q_offset;
+				spin_unlock_irqrestore(&eq->spinlock, flags);
+				max--;
+			} while (q_ofs == q_ofs2 && max > 0);
+			if (q_ofs == q_ofs2)
+				ehca_process_eq(shca, 0);
+		}
 	}
 	mod_timer(&poll_eqs_timer, jiffies + HZ);
 	spin_unlock(&shca_list_lock);
@@ -790,7 +810,7 @@
 	int ret;
 
 	printk(KERN_INFO "eHCA Infiniband Device Driver "
-	                 "(Rel.: SVNEHCA_0020)\n");
+	       "(Rel.: SVNEHCA_0021)\n");
 	idr_init(&ehca_qp_idr);
 	idr_init(&ehca_cq_idr);
 	spin_lock_init(&ehca_qp_idr_lock);
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.h b/drivers/infiniband/hw/ehca/ipz_pt_fn.h
index dc3bda2..8199c45 100644
--- a/drivers/infiniband/hw/ehca/ipz_pt_fn.h
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.h
@@ -79,7 +79,7 @@
 	if (q_offset >= queue->queue_length)
 		return NULL;
 	current_page = (queue->queue_pages)[q_offset >> EHCA_PAGESHIFT];
-	return  &current_page->entries[q_offset & (EHCA_PAGESIZE - 1)];
+	return &current_page->entries[q_offset & (EHCA_PAGESIZE - 1)];
 }
 
 /*
@@ -247,6 +247,15 @@
 	return ret;
 }
 
+static inline void *ipz_eqit_eq_peek_valid(struct ipz_queue *queue)
+{
+	void *ret = ipz_qeit_get(queue);
+	u32 qe = *(u8 *) ret;
+	if ((qe >> 7) != (queue->toggle_state & 1))
+		return NULL;
+	return ret;
+}
+
 /* returns address (GX) of first queue entry */
 static inline u64 ipz_qpt_get_firstpage(struct ipz_qpt *qpt)
 {
diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c
index 6e0f2b8..f6f9490 100644
--- a/drivers/infiniband/hw/ipath/ipath_dma.c
+++ b/drivers/infiniband/hw/ipath/ipath_dma.c
@@ -96,8 +96,8 @@
 	BUG_ON(!valid_dma_direction(direction));
 }
 
-int ipath_map_sg(struct ib_device *dev, struct scatterlist *sg, int nents,
-		 enum dma_data_direction direction)
+static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sg, int nents,
+			enum dma_data_direction direction)
 {
 	u64 addr;
 	int i;
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c
index 7468477..9934825 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6110.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c
@@ -1534,7 +1534,7 @@
  * @kbase: ipath_base_info pointer
  *
  * We set the PCIE flag because the lower bandwidth on PCIe vs
- * HyperTransport can affect some user packet algorithims.
+ * HyperTransport can affect some user packet algorithms.
  */
 static int ipath_ht_get_base_info(struct ipath_portdata *pd, void *kbase)
 {
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c
index ae8bf99..05918e1 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6120.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c
@@ -1293,7 +1293,7 @@
  * @kbase: ipath_base_info pointer
  *
  * We set the PCIE flag because the lower bandwidth on PCIe vs
- * HyperTransport can affect some user packet algorithims.
+ * HyperTransport can affect some user packet algorithms.
  */
 static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase)
 {
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 0b9d053..48f7c65 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -175,7 +175,9 @@
 		if (!ret) {
 			++chunk->npages;
 
-			if (!coherent && chunk->npages == MTHCA_ICM_CHUNK_LEN) {
+			if (coherent)
+				++chunk->nsg;
+			else if (chunk->npages == MTHCA_ICM_CHUNK_LEN) {
 				chunk->nsg = pci_map_sg(dev->pdev, chunk->mem,
 							chunk->npages,
 							PCI_DMA_BIDIRECTIONAL);
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 224c93d..71dc84b 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -573,6 +573,11 @@
 		goto out;
 	}
 
+	if (cur_state == new_state && cur_state == IB_QPS_RESET) {
+		err = 0;
+		goto out;
+	}
+
 	if ((attr_mask & IB_QP_PKEY_INDEX) &&
 	     attr->pkey_index >= dev->limits.pkey_table_len) {
 		mthca_dbg(dev, "P_Key index (%u) too large. max is %d\n",
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 2d48387..4d59682 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -145,7 +145,7 @@
 	for (; i >= 0; --i)
 		ib_dma_unmap_single(priv->ca, mapping[i + 1], PAGE_SIZE, DMA_FROM_DEVICE);
 
-	kfree_skb(skb);
+	dev_kfree_skb_any(skb);
 	return -ENOMEM;
 }
 
@@ -1138,7 +1138,7 @@
 	return -EINVAL;
 }
 
-static DEVICE_ATTR(mode, S_IWUGO | S_IRUGO, show_mode, set_mode);
+static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode);
 
 int ipoib_cm_add_mode_attr(struct net_device *dev)
 {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index fea737f..b303ce6 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -60,14 +60,11 @@
 /* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */
 struct ipoib_mcast {
 	struct ib_sa_mcmember_rec mcmember;
+	struct ib_sa_multicast	 *mc;
 	struct ipoib_ah          *ah;
 
 	struct rb_node    rb_node;
 	struct list_head  list;
-	struct completion done;
-
-	int                 query_id;
-	struct ib_sa_query *query;
 
 	unsigned long created;
 	unsigned long backoff;
@@ -299,18 +296,22 @@
 	return 0;
 }
 
-static void
+static int
 ipoib_mcast_sendonly_join_complete(int status,
-				   struct ib_sa_mcmember_rec *mcmember,
-				   void *mcast_ptr)
+				   struct ib_sa_multicast *multicast)
 {
-	struct ipoib_mcast *mcast = mcast_ptr;
+	struct ipoib_mcast *mcast = multicast->context;
 	struct net_device *dev = mcast->dev;
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 
+	/* We trap for port events ourselves. */
+	if (status == -ENETRESET)
+		return 0;
+
 	if (!status)
-		ipoib_mcast_join_finish(mcast, mcmember);
-	else {
+		status = ipoib_mcast_join_finish(mcast, &multicast->rec);
+
+	if (status) {
 		if (mcast->logcount++ < 20)
 			ipoib_dbg_mcast(netdev_priv(dev), "multicast join failed for "
 					IPOIB_GID_FMT ", status %d\n",
@@ -325,11 +326,10 @@
 		spin_unlock_irq(&priv->tx_lock);
 
 		/* Clear the busy flag so we try again */
-		clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
-		mcast->query = NULL;
+		status = test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY,
+					    &mcast->flags);
 	}
-
-	complete(&mcast->done);
+	return status;
 }
 
 static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast)
@@ -359,35 +359,33 @@
 	rec.port_gid = priv->local_gid;
 	rec.pkey     = cpu_to_be16(priv->pkey);
 
-	init_completion(&mcast->done);
-
-	ret = ib_sa_mcmember_rec_set(&ipoib_sa_client, priv->ca, priv->port, &rec,
-				     IB_SA_MCMEMBER_REC_MGID		|
-				     IB_SA_MCMEMBER_REC_PORT_GID	|
-				     IB_SA_MCMEMBER_REC_PKEY		|
-				     IB_SA_MCMEMBER_REC_JOIN_STATE,
-				     1000, GFP_ATOMIC,
-				     ipoib_mcast_sendonly_join_complete,
-				     mcast, &mcast->query);
-	if (ret < 0) {
-		ipoib_warn(priv, "ib_sa_mcmember_rec_set failed (ret = %d)\n",
+	mcast->mc = ib_sa_join_multicast(&ipoib_sa_client, priv->ca,
+					 priv->port, &rec,
+					 IB_SA_MCMEMBER_REC_MGID	|
+					 IB_SA_MCMEMBER_REC_PORT_GID	|
+					 IB_SA_MCMEMBER_REC_PKEY	|
+					 IB_SA_MCMEMBER_REC_JOIN_STATE,
+					 GFP_ATOMIC,
+					 ipoib_mcast_sendonly_join_complete,
+					 mcast);
+	if (IS_ERR(mcast->mc)) {
+		ret = PTR_ERR(mcast->mc);
+		clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
+		ipoib_warn(priv, "ib_sa_join_multicast failed (ret = %d)\n",
 			   ret);
 	} else {
 		ipoib_dbg_mcast(priv, "no multicast record for " IPOIB_GID_FMT
 				", starting join\n",
 				IPOIB_GID_ARG(mcast->mcmember.mgid));
-
-		mcast->query_id = ret;
 	}
 
 	return ret;
 }
 
-static void ipoib_mcast_join_complete(int status,
-				      struct ib_sa_mcmember_rec *mcmember,
-				      void *mcast_ptr)
+static int ipoib_mcast_join_complete(int status,
+				     struct ib_sa_multicast *multicast)
 {
-	struct ipoib_mcast *mcast = mcast_ptr;
+	struct ipoib_mcast *mcast = multicast->context;
 	struct net_device *dev = mcast->dev;
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 
@@ -395,24 +393,25 @@
 			" (status %d)\n",
 			IPOIB_GID_ARG(mcast->mcmember.mgid), status);
 
-	if (!status && !ipoib_mcast_join_finish(mcast, mcmember)) {
+	/* We trap for port events ourselves. */
+	if (status == -ENETRESET)
+		return 0;
+
+	if (!status)
+		status = ipoib_mcast_join_finish(mcast, &multicast->rec);
+
+	if (!status) {
 		mcast->backoff = 1;
 		mutex_lock(&mcast_mutex);
 		if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
 			queue_delayed_work(ipoib_workqueue,
 					   &priv->mcast_task, 0);
 		mutex_unlock(&mcast_mutex);
-		complete(&mcast->done);
-		return;
+		return 0;
 	}
 
-	if (status == -EINTR) {
-		complete(&mcast->done);
-		return;
-	}
-
-	if (status && mcast->logcount++ < 20) {
-		if (status == -ETIMEDOUT || status == -EINTR) {
+	if (mcast->logcount++ < 20) {
+		if (status == -ETIMEDOUT) {
 			ipoib_dbg_mcast(priv, "multicast join failed for " IPOIB_GID_FMT
 					", status %d\n",
 					IPOIB_GID_ARG(mcast->mcmember.mgid),
@@ -429,24 +428,18 @@
 	if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS)
 		mcast->backoff = IPOIB_MAX_BACKOFF_SECONDS;
 
+	/* Clear the busy flag so we try again */
+	status = test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
+
 	mutex_lock(&mcast_mutex);
-
 	spin_lock_irq(&priv->lock);
-	mcast->query = NULL;
-
-	if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) {
-		if (status == -ETIMEDOUT)
-			queue_delayed_work(ipoib_workqueue, &priv->mcast_task,
-					   0);
-		else
-			queue_delayed_work(ipoib_workqueue, &priv->mcast_task,
-					   mcast->backoff * HZ);
-	} else
-		complete(&mcast->done);
+	if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
+		queue_delayed_work(ipoib_workqueue, &priv->mcast_task,
+				   mcast->backoff * HZ);
 	spin_unlock_irq(&priv->lock);
 	mutex_unlock(&mcast_mutex);
 
-	return;
+	return status;
 }
 
 static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast,
@@ -495,15 +488,14 @@
 		rec.hop_limit	  = priv->broadcast->mcmember.hop_limit;
 	}
 
-	init_completion(&mcast->done);
-
-	ret = ib_sa_mcmember_rec_set(&ipoib_sa_client, priv->ca, priv->port,
-				     &rec, comp_mask, mcast->backoff * 1000,
-				     GFP_ATOMIC, ipoib_mcast_join_complete,
-				     mcast, &mcast->query);
-
-	if (ret < 0) {
-		ipoib_warn(priv, "ib_sa_mcmember_rec_set failed, status %d\n", ret);
+	set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
+	mcast->mc = ib_sa_join_multicast(&ipoib_sa_client, priv->ca, priv->port,
+					 &rec, comp_mask, GFP_KERNEL,
+					 ipoib_mcast_join_complete, mcast);
+	if (IS_ERR(mcast->mc)) {
+		clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
+		ret = PTR_ERR(mcast->mc);
+		ipoib_warn(priv, "ib_sa_join_multicast failed, status %d\n", ret);
 
 		mcast->backoff *= 2;
 		if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS)
@@ -515,8 +507,7 @@
 					   &priv->mcast_task,
 					   mcast->backoff * HZ);
 		mutex_unlock(&mcast_mutex);
-	} else
-		mcast->query_id = ret;
+	}
 }
 
 void ipoib_mcast_join_task(struct work_struct *work)
@@ -541,7 +532,7 @@
 			priv->local_rate = attr.active_speed *
 				ib_width_enum_to_int(attr.active_width);
 		} else
-		ipoib_warn(priv, "ib_query_port failed\n");
+			ipoib_warn(priv, "ib_query_port failed\n");
 	}
 
 	if (!priv->broadcast) {
@@ -568,7 +559,8 @@
 	}
 
 	if (!test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) {
-		ipoib_mcast_join(dev, priv->broadcast, 0);
+		if (!test_bit(IPOIB_MCAST_FLAG_BUSY, &priv->broadcast->flags))
+			ipoib_mcast_join(dev, priv->broadcast, 0);
 		return;
 	}
 
@@ -625,26 +617,9 @@
 	return 0;
 }
 
-static void wait_for_mcast_join(struct ipoib_dev_priv *priv,
-				struct ipoib_mcast *mcast)
-{
-	spin_lock_irq(&priv->lock);
-	if (mcast && mcast->query) {
-		ib_sa_cancel_query(mcast->query_id, mcast->query);
-		mcast->query = NULL;
-		spin_unlock_irq(&priv->lock);
-		ipoib_dbg_mcast(priv, "waiting for MGID " IPOIB_GID_FMT "\n",
-				IPOIB_GID_ARG(mcast->mcmember.mgid));
-		wait_for_completion(&mcast->done);
-	}
-	else
-		spin_unlock_irq(&priv->lock);
-}
-
 int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
-	struct ipoib_mcast *mcast;
 
 	ipoib_dbg_mcast(priv, "stopping multicast thread\n");
 
@@ -660,52 +635,27 @@
 	if (flush)
 		flush_workqueue(ipoib_workqueue);
 
-	wait_for_mcast_join(priv, priv->broadcast);
-
-	list_for_each_entry(mcast, &priv->multicast_list, list)
-		wait_for_mcast_join(priv, mcast);
-
 	return 0;
 }
 
 static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
-	struct ib_sa_mcmember_rec rec = {
-		.join_state = 1
-	};
 	int ret = 0;
 
-	if (!test_and_clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags))
-		return 0;
+	if (test_and_clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) {
+		ipoib_dbg_mcast(priv, "leaving MGID " IPOIB_GID_FMT "\n",
+				IPOIB_GID_ARG(mcast->mcmember.mgid));
 
-	ipoib_dbg_mcast(priv, "leaving MGID " IPOIB_GID_FMT "\n",
-			IPOIB_GID_ARG(mcast->mcmember.mgid));
+		/* Remove ourselves from the multicast group */
+		ret = ipoib_mcast_detach(dev, be16_to_cpu(mcast->mcmember.mlid),
+					 &mcast->mcmember.mgid);
+		if (ret)
+			ipoib_warn(priv, "ipoib_mcast_detach failed (result = %d)\n", ret);
+	}
 
-	rec.mgid     = mcast->mcmember.mgid;
-	rec.port_gid = priv->local_gid;
-	rec.pkey     = cpu_to_be16(priv->pkey);
-
-	/* Remove ourselves from the multicast group */
-	ret = ipoib_mcast_detach(dev, be16_to_cpu(mcast->mcmember.mlid),
-				 &mcast->mcmember.mgid);
-	if (ret)
-		ipoib_warn(priv, "ipoib_mcast_detach failed (result = %d)\n", ret);
-
-	/*
-	 * Just make one shot at leaving and don't wait for a reply;
-	 * if we fail, too bad.
-	 */
-	ret = ib_sa_mcmember_rec_delete(&ipoib_sa_client, priv->ca, priv->port, &rec,
-					IB_SA_MCMEMBER_REC_MGID		|
-					IB_SA_MCMEMBER_REC_PORT_GID	|
-					IB_SA_MCMEMBER_REC_PKEY		|
-					IB_SA_MCMEMBER_REC_JOIN_STATE,
-					0, GFP_ATOMIC, NULL,
-					mcast, &mcast->query);
-	if (ret < 0)
-		ipoib_warn(priv, "ib_sa_mcmember_rec_delete failed "
-			   "for leave (result = %d)\n", ret);
+	if (test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
+		ib_sa_free_multicast(mcast->mc);
 
 	return 0;
 }
@@ -758,7 +708,7 @@
 			dev_kfree_skb_any(skb);
 		}
 
-		if (mcast->query)
+		if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
 			ipoib_dbg_mcast(priv, "no address vector, "
 					"but multicast join already started\n");
 		else if (test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags))
@@ -916,7 +866,6 @@
 
 	/* We have to cancel outside of the spinlock */
 	list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
-		wait_for_mcast_join(priv, mcast);
 		ipoib_mcast_leave(mcast->dev, mcast);
 		ipoib_mcast_free(mcast);
 	}
diff --git a/drivers/input/input.c b/drivers/input/input.c
index efa1b1f..a9a706f 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -588,18 +588,9 @@
 static ssize_t input_dev_show_##name(struct class_device *dev, char *buf)	\
 {										\
 	struct input_dev *input_dev = to_input_dev(dev);			\
-	int retval;								\
 										\
-	retval = mutex_lock_interruptible(&input_dev->mutex);			\
-	if (retval)								\
-		return retval;							\
-										\
-	retval = scnprintf(buf, PAGE_SIZE,					\
-			   "%s\n", input_dev->name ? input_dev->name : "");	\
-										\
-	mutex_unlock(&input_dev->mutex);					\
-										\
-	return retval;								\
+	return scnprintf(buf, PAGE_SIZE, "%s\n",				\
+			 input_dev->name ? input_dev->name : "");		\
 }										\
 static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL);
 
@@ -1049,10 +1040,6 @@
 	sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
 	sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
 
-	mutex_lock(&dev->mutex);
-	dev->name = dev->phys = dev->uniq = NULL;
-	mutex_unlock(&dev->mutex);
-
 	class_device_unregister(&dev->cdev);
 
 	input_wakeup_procfs_readers();
diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c
index e608691..b0f5541 100644
--- a/drivers/input/joystick/amijoy.c
+++ b/drivers/input/joystick/amijoy.c
@@ -50,8 +50,6 @@
 module_param_array_named(map, amijoy, uint, NULL, 0);
 MODULE_PARM_DESC(map, "Map of attached joysticks in form of <a>,<b> (default is 0,1)");
 
-__obsolete_setup("amijoy=");
-
 static int amijoy_used;
 static DEFINE_MUTEX(amijoy_mutex);
 static struct input_dev *amijoy_dev[2];
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index 7ef6845..51f1e4b 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -58,8 +58,6 @@
 module_param_array_named(map, js, charp, &js_nargs, 0);
 MODULE_PARM_DESC(map, "Describes analog joysticks type/capabilities");
 
-__obsolete_setup("js=");
-
 /*
  * Times, feature definitions.
  */
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
index 5080e15..b41bd2e 100644
--- a/drivers/input/joystick/db9.c
+++ b/drivers/input/joystick/db9.c
@@ -59,10 +59,6 @@
 module_param_array_named(dev3, db9[2].args, int, &db9[2].nargs, 0);
 MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)");
 
-__obsolete_setup("db9=");
-__obsolete_setup("db9_2=");
-__obsolete_setup("db9_3=");
-
 #define DB9_ARG_PARPORT		0
 #define DB9_ARG_MODE		1
 
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
index fe12aa3..711e4b3 100644
--- a/drivers/input/joystick/gamecon.c
+++ b/drivers/input/joystick/gamecon.c
@@ -60,10 +60,6 @@
 module_param_array_named(map3, gc[2].args, int, &gc[2].nargs, 0);
 MODULE_PARM_DESC(map3, "Describes third set of devices");
 
-__obsolete_setup("gc=");
-__obsolete_setup("gc_2=");
-__obsolete_setup("gc_3=");
-
 /* see also gs_psx_delay parameter in PSX support section */
 
 #define GC_SNES		1
@@ -403,8 +399,6 @@
 module_param_named(psx_delay, gc_psx_delay, uint, 0);
 MODULE_PARM_DESC(psx_delay, "Delay when accessing Sony PSX controller (usecs)");
 
-__obsolete_setup("gc_psx_delay=");
-
 static short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y };
 static short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y,
 				BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR };
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
index 5570fd5..037d348 100644
--- a/drivers/input/joystick/turbografx.c
+++ b/drivers/input/joystick/turbografx.c
@@ -60,10 +60,6 @@
 module_param_array_named(map3, tgfx[2].args, int, &tgfx[2].nargs, 0);
 MODULE_PARM_DESC(map3, "Describes third set of devices");
 
-__obsolete_setup("tgfx=");
-__obsolete_setup("tgfx_2=");
-__obsolete_setup("tgfx_3=");
-
 #define TGFX_REFRESH_TIME	HZ/100	/* 10 ms */
 
 #define TGFX_TRIGGER		0x08
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 1b81a72..6450968 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -215,11 +215,11 @@
 	  module will be called aaed2000_kbd.
 
 config KEYBOARD_GPIO
-        tristate "Buttons on CPU GPIOs (PXA)"
-        depends on ARCH_PXA
+	tristate "Buttons on CPU GPIOs (PXA)"
+	depends on (ARCH_SA1100 || ARCH_PXA || ARCH_S3C2410)
 	help
 	  This driver implements support for buttons connected
-	  directly to GPIO pins of PXA CPUs.
+	  directly to GPIO pins of SA1100, PXA or S3C24xx CPUs.
 
 	  Say Y here if your device has buttons connected
 	  directly to GPIO pins of the CPU.
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index c621a91..6638770 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -63,10 +63,6 @@
 module_param_named(extra, atkbd_extra, bool, 0);
 MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards");
 
-__obsolete_setup("atkbd_set=");
-__obsolete_setup("atkbd_reset");
-__obsolete_setup("atkbd_softrepeat=");
-
 /*
  * Scancode to keycode tables. These are just the default setting, and
  * are loadable via an userland utility.
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index 7ad479e..fa03a00 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -24,7 +24,7 @@
 #include <linux/input.h>
 #include <linux/irq.h>
 
-#include <asm/arch/pxa-regs.h>
+#include <asm/gpio.h>
 #include <asm/arch/hardware.h>
 
 #include <asm/hardware/gpio_keys.h>
@@ -38,8 +38,8 @@
 
 	for (i = 0; i < pdata->nbuttons; i++) {
 		int gpio = pdata->buttons[i].gpio;
-		if (irq == IRQ_GPIO(gpio)) {
-			int state = ((GPLR(gpio) & GPIO_bit(gpio)) ? 1 : 0) ^ (pdata->buttons[i].active_low);
+		if (irq == gpio_to_irq(gpio)) {
+			int state = (gpio_get_value(gpio) ? 1 : 0) ^ (pdata->buttons[i].active_low);
 
 			input_report_key(input, pdata->buttons[i].keycode, state);
 			input_sync(input);
@@ -75,14 +75,15 @@
 
 	for (i = 0; i < pdata->nbuttons; i++) {
 		int code = pdata->buttons[i].keycode;
-		int irq = IRQ_GPIO(pdata->buttons[i].gpio);
+		int irq = gpio_to_irq(pdata->buttons[i].gpio);
 
 		set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
 		error = request_irq(irq, gpio_keys_isr, IRQF_SAMPLE_RANDOM,
 				     pdata->buttons[i].desc ? pdata->buttons[i].desc : "gpio_keys",
 				     pdev);
 		if (error) {
-			printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n", irq, ret);
+			printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n",
+				irq, error);
 			goto fail;
 		}
 		set_bit(code, input->keybit);
@@ -98,7 +99,7 @@
 
  fail:
 	for (i = i - 1; i >= 0; i--)
-		free_irq(IRQ_GPIO(pdata->buttons[i].gpio), pdev);
+		free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev);
 
 	input_free_device(input);
 
@@ -112,7 +113,7 @@
 	int i;
 
 	for (i = 0; i < pdata->nbuttons; i++) {
-		int irq = IRQ_GPIO(pdata->buttons[i].gpio);
+		int irq = gpio_to_irq(pdata->buttons[i].gpio);
 		free_irq(irq, pdev);
 	}
 
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
index 255a6ec..4de4dc2 100644
--- a/drivers/input/keyboard/hilkbd.c
+++ b/drivers/input/keyboard/hilkbd.c
@@ -294,8 +294,10 @@
 	disable_irq(HIL_IRQ);
 	free_irq(HIL_IRQ, hil_dev.dev_id);
 err2:
+#if defined(CONFIG_HP300)
 	release_region(HILBASE + HIL_DATA, 2);
 err1:
+#endif
 	input_free_device(hil_dev.dev);
 	hil_dev.dev = NULL;
 	return err;
diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c
index 701ebd5..79b624f 100644
--- a/drivers/input/mouse/inport.c
+++ b/drivers/input/mouse/inport.c
@@ -84,8 +84,6 @@
 module_param_named(irq, inport_irq, uint, 0);
 MODULE_PARM_DESC(irq, "IRQ number (5=default)");
 
-__obsolete_setup("inport_irq=");
-
 static struct input_dev *inport_dev;
 
 static irqreturn_t inport_interrupt(int irq, void *dev_id)
diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c
index db20599..26c3b2e 100644
--- a/drivers/input/mouse/logibm.c
+++ b/drivers/input/mouse/logibm.c
@@ -75,8 +75,6 @@
 module_param_named(irq, logibm_irq, uint, 0);
 MODULE_PARM_DESC(irq, "IRQ number (5=default)");
 
-__obsolete_setup("logibm_irq=");
-
 static struct input_dev *logibm_dev;
 
 static irqreturn_t logibm_interrupt(int irq, void *dev_id)
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index a0e4a03..0fe5869 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -93,12 +93,6 @@
 	.attrs	= psmouse_attributes,
 };
 
-__obsolete_setup("psmouse_noext");
-__obsolete_setup("psmouse_resolution=");
-__obsolete_setup("psmouse_smartscroll=");
-__obsolete_setup("psmouse_resetafter=");
-__obsolete_setup("psmouse_rate=");
-
 /*
  * psmouse_mutex protects all operations changing state of mouse
  * (connecting, disconnecting, changing rate or resolution via
@@ -987,8 +981,36 @@
 static void psmouse_cleanup(struct serio *serio)
 {
 	struct psmouse *psmouse = serio_get_drvdata(serio);
+	struct psmouse *parent = NULL;
+
+	mutex_lock(&psmouse_mutex);
+
+	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
+		parent = serio_get_drvdata(serio->parent);
+		psmouse_deactivate(parent);
+	}
+
+	psmouse_deactivate(psmouse);
+
+	if (psmouse->cleanup)
+		psmouse->cleanup(psmouse);
 
 	psmouse_reset(psmouse);
+
+/*
+ * Some boxes, such as HP nx7400, get terribly confused if mouse
+ * is not fully enabled before suspending/shutting down.
+ */
+	ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE);
+
+	if (parent) {
+		if (parent->pt_deactivate)
+			parent->pt_deactivate(parent);
+
+		psmouse_activate(parent);
+	}
+
+	mutex_unlock(&psmouse_mutex);
 }
 
 /*
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 1b74cae..cf1de95 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -68,6 +68,7 @@
 
 	int (*reconnect)(struct psmouse *psmouse);
 	void (*disconnect)(struct psmouse *psmouse);
+	void (*cleanup)(struct psmouse *psmouse);
 	int (*poll)(struct psmouse *psmouse);
 
 	void (*pt_activate)(struct psmouse *psmouse);
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 49ac696..f0f9413 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -652,6 +652,7 @@
 	psmouse->set_rate = synaptics_set_rate;
 	psmouse->disconnect = synaptics_disconnect;
 	psmouse->reconnect = synaptics_reconnect;
+	psmouse->cleanup = synaptics_reset;
 	psmouse->pktsize = 6;
 	/* Synaptics can usually stay in sync without extra help */
 	psmouse->resync_time = 0;
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index c3fdfc1..ec195a3 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -76,13 +76,6 @@
 MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off");
 #endif
 
-__obsolete_setup("i8042_noaux");
-__obsolete_setup("i8042_nomux");
-__obsolete_setup("i8042_unlock");
-__obsolete_setup("i8042_reset");
-__obsolete_setup("i8042_direct");
-__obsolete_setup("i8042_dumbkbd");
-
 #include "i8042.h"
 
 static DEFINE_SPINLOCK(i8042_lock);
@@ -724,7 +717,7 @@
 	if (~i8042_read_status() & I8042_STR_KEYLOCK) {
 		if (i8042_unlock)
 			i8042_ctr |= I8042_CTR_IGNKEYLOCK;
-		 else
+		else
 			printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n");
 	}
 	spin_unlock_irqrestore(&i8042_lock, flags);
@@ -791,27 +784,6 @@
 
 
 /*
- * Here we try to reset everything back to a state in which the BIOS will be
- * able to talk to the hardware when rebooting.
- */
-
-static void i8042_controller_cleanup(void)
-{
-	int i;
-
-/*
- * Reset anything that is connected to the ports.
- */
-
-	for (i = 0; i < I8042_NUM_PORTS; i++)
-		if (i8042_ports[i].serio)
-			serio_cleanup(i8042_ports[i].serio);
-
-	i8042_controller_reset();
-}
-
-
-/*
  * i8042_panic_blink() will flash the keyboard LEDs and is called when
  * kernel panics. Flashing LEDs is useful for users running X who may
  * not see the console and will help distingushing panics from "real"
@@ -857,13 +829,22 @@
 
 #undef DELAY
 
+#ifdef CONFIG_PM
 /*
- * Here we try to restore the original BIOS settings
+ * Here we try to restore the original BIOS settings. We only want to
+ * do that once, when we really suspend, not when we taking memory
+ * snapshot for swsusp (in this case we'll perform required cleanup
+ * as part of shutdown process).
  */
 
 static int i8042_suspend(struct platform_device *dev, pm_message_t state)
 {
-	i8042_controller_cleanup();
+	if (dev->dev.power.power_state.event != state.event) {
+		if (state.event == PM_EVENT_SUSPEND)
+			i8042_controller_reset();
+
+		dev->dev.power.power_state = state;
+	}
 
 	return 0;
 }
@@ -877,6 +858,12 @@
 {
 	int error;
 
+/*
+ * Do not bother with restoring state if we haven't suspened yet
+ */
+	if (dev->dev.power.power_state.event == PM_EVENT_ON)
+		return 0;
+
 	error = i8042_controller_check();
 	if (error)
 		return error;
@@ -886,9 +873,12 @@
 		return error;
 
 /*
- * Restore pre-resume CTR value and disable all ports
+ * Restore original CTR value and disable all ports
  */
 
+	i8042_ctr = i8042_initial_ctr;
+	if (i8042_direct)
+		i8042_ctr &= ~I8042_CTR_XLATE;
 	i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS;
 	i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT);
 	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
@@ -909,8 +899,11 @@
 
 	i8042_interrupt(0, NULL);
 
+	dev->dev.power.power_state = PMSG_ON;
+
 	return 0;
 }
+#endif /* CONFIG_PM */
 
 /*
  * We need to reset the 8042 back to original mode on system shutdown,
@@ -919,7 +912,7 @@
 
 static void i8042_shutdown(struct platform_device *dev)
 {
-	i8042_controller_cleanup();
+	i8042_controller_reset();
 }
 
 static int __devinit i8042_create_kbd_port(void)
@@ -1154,9 +1147,11 @@
 	},
 	.probe		= i8042_probe,
 	.remove		= __devexit_p(i8042_remove),
+	.shutdown	= i8042_shutdown,
+#ifdef CONFIG_PM
 	.suspend	= i8042_suspend,
 	.resume		= i8042_resume,
-	.shutdown	= i8042_shutdown,
+#endif
 };
 
 static int __init i8042_init(void)
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index b3e84d3..10d9d74 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -97,7 +97,7 @@
 
 int ps2_is_keyboard_id(char id_byte)
 {
-	const static char keyboard_ids[] = {
+	static const char keyboard_ids[] = {
 		0xab,	/* Regular keyboards		*/
 		0xac,	/* NCD Sun keyboard		*/
 		0x2b,	/* Trust keyboard, translated	*/
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 17c8c63..a15e531 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -778,6 +778,19 @@
 	return 0;
 }
 
+static void serio_cleanup(struct serio *serio)
+{
+	if (serio->drv && serio->drv->cleanup)
+		serio->drv->cleanup(serio);
+}
+
+static void serio_shutdown(struct device *dev)
+{
+	struct serio *serio = to_serio_port(dev);
+
+	serio_cleanup(serio);
+}
+
 static void serio_attach_driver(struct serio_driver *drv)
 {
 	int error;
@@ -910,11 +923,25 @@
 
 #endif /* CONFIG_HOTPLUG */
 
+#ifdef CONFIG_PM
+static int serio_suspend(struct device *dev, pm_message_t state)
+{
+	if (dev->power.power_state.event != state.event) {
+		if (state.event == PM_EVENT_SUSPEND)
+			serio_cleanup(to_serio_port(dev));
+
+		dev->power.power_state = state;
+	}
+
+	return 0;
+}
+
 static int serio_resume(struct device *dev)
 {
 	struct serio *serio = to_serio_port(dev);
 
-	if (serio_reconnect_driver(serio)) {
+	if (dev->power.power_state.event != PM_EVENT_ON &&
+	    serio_reconnect_driver(serio)) {
 		/*
 		 * Driver re-probing can take a while, so better let kseriod
 		 * deal with it.
@@ -922,8 +949,11 @@
 		serio_rescan(serio);
 	}
 
+	dev->power.power_state = PMSG_ON;
+
 	return 0;
 }
+#endif /* CONFIG_PM */
 
 /* called from serio_driver->connect/disconnect methods under serio_mutex */
 int serio_open(struct serio *serio, struct serio_driver *drv)
@@ -974,7 +1004,11 @@
 	.uevent		= serio_uevent,
 	.probe		= serio_driver_probe,
 	.remove		= serio_driver_remove,
+	.shutdown	= serio_shutdown,
+#ifdef CONFIG_PM
+	.suspend	= serio_suspend,
 	.resume		= serio_resume,
+#endif
 };
 
 static int __init serio_init(void)
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 4e3f127..1b2df80 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -1680,7 +1680,7 @@
 	 * - we hit a gap in the sequence, so no reassembly/processing is 
 	 *   possible ('start' would be set to NULL)
 	 *
-	 * algorightm for this code is derived from code in the book
+	 * algorithm for this code is derived from code in the book
 	 * 'PPP Design And Debugging' by James Carlson (Addison-Wesley)
 	 */
   	while (start != NULL || newfrag != NULL) {
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index e859722..7c42d53 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -915,7 +915,7 @@
 			fetunesettings.parameters.inversion = INVERSION_AUTO;
 		}
 		if (fe->ops.info.type == FE_OFDM) {
-			/* without hierachical coding code_rate_LP is irrelevant,
+			/* without hierarchical coding code_rate_LP is irrelevant,
 			 * so we tolerate the otherwise invalid FEC_NONE setting */
 			if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE &&
 			    fepriv->parameters.u.ofdm.code_rate_LP == FEC_NONE)
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
index adbabfd..b6adea5 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -239,7 +239,7 @@
 		default:
 			return -EINVAL;
 	}
-	deb_setf("hierachy: ");
+	deb_setf("hierarchy: ");
 	switch (ofdm->hierarchy_information) {
 		case HIERARCHY_NONE:
 			deb_setf("none ");
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
index 9846c46..122496f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -158,7 +158,7 @@
 }
 
 
-const static struct pvr2_i2c_handler_functions msp3400_funcs = {
+static const struct pvr2_i2c_handler_functions msp3400_funcs = {
 	.detach = (void (*)(void *))pvr2_msp3400_detach,
 	.check = (int (*)(void *))msp3400_check,
 	.update = (void (*)(void *))msp3400_update,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 848fb233..8df969c 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -226,7 +226,7 @@
 }
 
 
-const static struct pvr2_i2c_handler_functions hfuncs = {
+static const struct pvr2_i2c_handler_functions hfuncs = {
 	.detach = (void (*)(void *))decoder_detach,
 	.check = (int (*)(void *))decoder_check,
 	.update = (void (*)(void *))decoder_update,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.c b/drivers/media/video/pvrusb2/pvrusb2-std.c
index f95c598..c089255 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-std.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-std.c
@@ -78,14 +78,14 @@
 #define CSTD_ALL (CSTD_PAL|CSTD_NTSC|CSTD_SECAM)
 
 /* Mapping of standard bits to color system */
-const static struct std_name std_groups[] = {
+static const struct std_name std_groups[] = {
 	{"PAL",CSTD_PAL},
 	{"NTSC",CSTD_NTSC},
 	{"SECAM",CSTD_SECAM},
 };
 
 /* Mapping of standard bits to modulation system */
-const static struct std_name std_items[] = {
+static const struct std_name std_items[] = {
 	{"B",TSTD_B},
 	{"B1",TSTD_B1},
 	{"D",TSTD_D},
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.c b/drivers/media/video/pvrusb2/pvrusb2-tuner.c
index af9f246..bb17db3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-tuner.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-tuner.c
@@ -80,7 +80,7 @@
 }
 
 
-const static struct pvr2_i2c_handler_functions tuner_funcs = {
+static const struct pvr2_i2c_handler_functions tuner_funcs = {
 	.detach = (void (*)(void *))pvr2_tuner_detach,
 	.check = (int (*)(void *))tuner_check,
 	.update = (void (*)(void *))tuner_update,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
index 05f2cdd..2a82646 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -201,7 +201,7 @@
 }
 
 
-const static struct pvr2_i2c_handler_functions hfuncs = {
+static const struct pvr2_i2c_handler_functions hfuncs = {
 	.detach = (void (*)(void *))decoder_detach,
 	.check = (int (*)(void *))decoder_check,
 	.update = (void (*)(void *))decoder_update,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
index 2413e51..7794c34 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
@@ -126,7 +126,7 @@
 }
 
 
-const static struct pvr2_i2c_handler_functions hfuncs = {
+static const struct pvr2_i2c_handler_functions hfuncs = {
 	.detach = (void (*)(void *))wm8775_detach,
 	.check = (int (*)(void *))wm8775_check,
 	.update = (void (*)(void *))wm8775_update,
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index bedae4a..80b199f 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -107,4 +107,19 @@
 
 	  If you have an MSI S270 laptop, say Y or M here.
 
+config SONY_LAPTOP
+	tristate "Sony Laptop Extras"
+	depends on X86 && ACPI
+	select BACKLIGHT_CLASS_DEVICE
+	  ---help---
+	  This mini-driver drives the SNC device present in the ACPI BIOS of
+	  the Sony Vaio laptops.
+
+	  It gives access to some extra laptop functionalities. In its current
+	  form, this driver let the user set or query the screen brightness
+	  through the backlight subsystem and remove/apply power to some
+	  devices.
+
+	  Read <file:Documentation/sony-laptop.txt> for more information.
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 35da53c..7793ccd 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -11,3 +11,4 @@
 obj-$(CONFIG_TIFM_CORE)       	+= tifm_core.o
 obj-$(CONFIG_TIFM_7XX1)       	+= tifm_7xx1.o
 obj-$(CONFIG_SGI_IOC4)		+= ioc4.o
+obj-$(CONFIG_SONY_LAPTOP)	+= sony-laptop.o
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index 861c399..e4e2b70 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -1088,11 +1088,6 @@
 	if (acpi_disabled)
 		return -ENODEV;
 
-	if (!acpi_specific_hotkey_enabled) {
-		printk(ASUS_ERR "Using generic hotkey driver\n");
-		return -ENODEV;
-	}
-
 	result = acpi_bus_register_driver(&asus_hotk_driver);
 	if (result < 0)
 		return result;
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
new file mode 100644
index 0000000..cabbed0
--- /dev/null
+++ b/drivers/misc/sony-laptop.c
@@ -0,0 +1,562 @@
+/*
+ * ACPI Sony Notebook Control Driver (SNC)
+ *
+ * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net>
+ * Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
+ *
+ * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c
+ * which are copyrighted by their respective authors.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+#include <asm/uaccess.h>
+
+#define ACPI_SNC_CLASS		"sony"
+#define ACPI_SNC_HID		"SNY5001"
+#define ACPI_SNC_DRIVER_NAME	"ACPI Sony Notebook Control Driver v0.4"
+
+/* the device uses 1-based values, while the backlight subsystem uses
+   0-based values */
+#define SONY_MAX_BRIGHTNESS	8
+
+#define LOG_PFX			KERN_WARNING "sony-laptop: "
+
+MODULE_AUTHOR("Stelian Pop, Mattia Dongili");
+MODULE_DESCRIPTION(ACPI_SNC_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+static int debug;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help "
+		 "the development of this driver");
+
+static ssize_t sony_acpi_show(struct device *, struct device_attribute *,
+			      char *);
+static ssize_t sony_acpi_store(struct device *, struct device_attribute *,
+			       const char *, size_t);
+static int boolean_validate(const int, const int);
+static int brightness_default_validate(const int, const int);
+
+#define SNC_VALIDATE_IN		0
+#define SNC_VALIDATE_OUT	1
+
+struct sony_acpi_value {
+	char *name;		/* name of the entry */
+	char **acpiget;		/* names of the ACPI get function */
+	char **acpiset;		/* names of the ACPI set function */
+	int (*validate)(const int, const int);	/* input/output validation */
+	int value;		/* current setting */
+	int valid;		/* Has ever been set */
+	int debug;		/* active only in debug mode ? */
+	struct device_attribute devattr;	/* sysfs atribute */
+};
+
+#define HANDLE_NAMES(_name, _values...) \
+	static char *snc_##_name[] = { _values, NULL }
+
+#define SONY_ACPI_VALUE(_name, _getters, _setters, _validate, _debug) \
+	{ \
+		.name		= __stringify(_name), \
+		.acpiget	= _getters, \
+		.acpiset	= _setters, \
+		.validate	= _validate, \
+		.debug		= _debug, \
+		.devattr	= __ATTR(_name, 0, sony_acpi_show, sony_acpi_store), \
+	}
+
+#define SONY_ACPI_VALUE_NULL	{ .name = NULL }
+
+HANDLE_NAMES(fnkey_get, "GHKE");
+
+HANDLE_NAMES(brightness_def_get, "GPBR");
+HANDLE_NAMES(brightness_def_set, "SPBR");
+
+HANDLE_NAMES(cdpower_get, "GCDP");
+HANDLE_NAMES(cdpower_set, "SCDP", "CDPW");
+
+HANDLE_NAMES(audiopower_get, "GAZP");
+HANDLE_NAMES(audiopower_set, "AZPW");
+
+HANDLE_NAMES(lanpower_get, "GLNP");
+HANDLE_NAMES(lanpower_set, "LNPW");
+
+HANDLE_NAMES(PID_get, "GPID");
+
+HANDLE_NAMES(CTR_get, "GCTR");
+HANDLE_NAMES(CTR_set, "SCTR");
+
+HANDLE_NAMES(PCR_get, "GPCR");
+HANDLE_NAMES(PCR_set, "SPCR");
+
+HANDLE_NAMES(CMI_get, "GCMI");
+HANDLE_NAMES(CMI_set, "SCMI");
+
+static struct sony_acpi_value sony_acpi_values[] = {
+	SONY_ACPI_VALUE(brightness_default, snc_brightness_def_get,
+			snc_brightness_def_set, brightness_default_validate, 0),
+	SONY_ACPI_VALUE(fnkey, snc_fnkey_get, NULL, NULL, 0),
+	SONY_ACPI_VALUE(cdpower, snc_cdpower_get, snc_cdpower_set, boolean_validate, 0),
+	SONY_ACPI_VALUE(audiopower, snc_audiopower_get, snc_audiopower_set,
+			boolean_validate, 0),
+	SONY_ACPI_VALUE(lanpower, snc_lanpower_get, snc_lanpower_set,
+			boolean_validate, 1),
+	/* unknown methods */
+	SONY_ACPI_VALUE(PID, snc_PID_get, NULL, NULL, 1),
+	SONY_ACPI_VALUE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1),
+	SONY_ACPI_VALUE(PCR, snc_PCR_get, snc_PCR_set, NULL, 1),
+	SONY_ACPI_VALUE(CMI, snc_CMI_get, snc_CMI_set, NULL, 1),
+	SONY_ACPI_VALUE_NULL
+};
+
+static acpi_handle sony_acpi_handle;
+static struct acpi_device *sony_acpi_acpi_device = NULL;
+
+/*
+ * acpi_evaluate_object wrappers
+ */
+static int acpi_callgetfunc(acpi_handle handle, char *name, int *result)
+{
+	struct acpi_buffer output;
+	union acpi_object out_obj;
+	acpi_status status;
+
+	output.length = sizeof(out_obj);
+	output.pointer = &out_obj;
+
+	status = acpi_evaluate_object(handle, name, NULL, &output);
+	if ((status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER)) {
+		*result = out_obj.integer.value;
+		return 0;
+	}
+
+	printk(LOG_PFX "acpi_callreadfunc failed\n");
+
+	return -1;
+}
+
+static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
+			    int *result)
+{
+	struct acpi_object_list params;
+	union acpi_object in_obj;
+	struct acpi_buffer output;
+	union acpi_object out_obj;
+	acpi_status status;
+
+	params.count = 1;
+	params.pointer = &in_obj;
+	in_obj.type = ACPI_TYPE_INTEGER;
+	in_obj.integer.value = value;
+
+	output.length = sizeof(out_obj);
+	output.pointer = &out_obj;
+
+	status = acpi_evaluate_object(handle, name, &params, &output);
+	if (status == AE_OK) {
+		if (result != NULL) {
+			if (out_obj.type != ACPI_TYPE_INTEGER) {
+				printk(LOG_PFX "acpi_evaluate_object bad "
+				       "return type\n");
+				return -1;
+			}
+			*result = out_obj.integer.value;
+		}
+		return 0;
+	}
+
+	printk(LOG_PFX "acpi_evaluate_object failed\n");
+
+	return -1;
+}
+
+/*
+ * sony_acpi_values input/output validate functions
+ */
+
+/* brightness_default_validate:
+ *
+ * manipulate input output values to keep consistency with the
+ * backlight framework for which brightness values are 0-based.
+ */
+static int brightness_default_validate(const int direction, const int value)
+{
+	switch (direction) {
+		case SNC_VALIDATE_OUT:
+			return value - 1;
+		case SNC_VALIDATE_IN:
+			if (value >= 0 && value < SONY_MAX_BRIGHTNESS)
+				return value + 1;
+	}
+	return -EINVAL;
+}
+
+/* boolean_validate:
+ *
+ * on input validate boolean values 0/1, on output just pass the
+ * received value.
+ */
+static int boolean_validate(const int direction, const int value)
+{
+	if (direction == SNC_VALIDATE_IN) {
+		if (value != 0 && value != 1)
+			return -EINVAL;
+	}
+	return value;
+}
+
+/*
+ * Sysfs show/store common to all sony_acpi_values
+ */
+static ssize_t sony_acpi_show(struct device *dev, struct device_attribute *attr,
+			      char *buffer)
+{
+	int value;
+	struct sony_acpi_value *item =
+	    container_of(attr, struct sony_acpi_value, devattr);
+
+	if (!*item->acpiget)
+		return -EIO;
+
+	if (acpi_callgetfunc(sony_acpi_handle, *item->acpiget, &value) < 0)
+		return -EIO;
+
+	if (item->validate)
+		value = item->validate(SNC_VALIDATE_OUT, value);
+
+	return snprintf(buffer, PAGE_SIZE, "%d\n", value);
+}
+
+static ssize_t sony_acpi_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buffer, size_t count)
+{
+	int value;
+	struct sony_acpi_value *item =
+	    container_of(attr, struct sony_acpi_value, devattr);
+
+	if (!item->acpiset)
+		return -EIO;
+
+	if (count > 31)
+		return -EINVAL;
+
+	value = simple_strtoul(buffer, NULL, 10);
+
+	if (item->validate)
+		value = item->validate(SNC_VALIDATE_IN, value);
+
+	if (value < 0)
+		return value;
+
+	if (acpi_callsetfunc(sony_acpi_handle, *item->acpiset, value, NULL) < 0)
+		return -EIO;
+	item->value = value;
+	item->valid = 1;
+	return count;
+}
+
+/*
+ * Platform device
+ */
+static struct platform_driver sncpf_driver = {
+	.driver = {
+		   .name = "sony-laptop",
+		   .owner = THIS_MODULE,
+		   }
+};
+static struct platform_device *sncpf_device;
+
+static int sony_snc_pf_add(void)
+{
+	acpi_handle handle;
+	struct sony_acpi_value *item;
+	int ret = 0;
+
+	ret = platform_driver_register(&sncpf_driver);
+	if (ret)
+		goto out;
+
+	sncpf_device = platform_device_alloc("sony-laptop", -1);
+	if (!sncpf_device) {
+		ret = -ENOMEM;
+		goto out_platform_registered;
+	}
+
+	ret = platform_device_add(sncpf_device);
+	if (ret)
+		goto out_platform_alloced;
+
+	for (item = sony_acpi_values; item->name; ++item) {
+
+		if (!debug && item->debug)
+			continue;
+
+		/* find the available acpiget as described in the DSDT */
+		for (; item->acpiget && *item->acpiget; ++item->acpiget) {
+			if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle,
+							 *item->acpiget,
+							 &handle))) {
+				if (debug)
+					printk(LOG_PFX "Found %s getter: %s\n",
+					       item->name, *item->acpiget);
+				item->devattr.attr.mode |= S_IRUGO;
+				break;
+			}
+		}
+
+		/* find the available acpiset as described in the DSDT */
+		for (; item->acpiset && *item->acpiset; ++item->acpiset) {
+			if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle,
+							 *item->acpiset,
+							 &handle))) {
+				if (debug)
+					printk(LOG_PFX "Found %s setter: %s\n",
+					       item->name, *item->acpiset);
+				item->devattr.attr.mode |= S_IWUSR;
+				break;
+			}
+		}
+
+		if (item->devattr.attr.mode != 0) {
+			ret =
+			    device_create_file(&sncpf_device->dev,
+					       &item->devattr);
+			if (ret)
+				goto out_sysfs;
+		}
+	}
+
+	return 0;
+
+      out_sysfs:
+	for (item = sony_acpi_values; item->name; ++item) {
+		device_remove_file(&sncpf_device->dev, &item->devattr);
+	}
+	platform_device_del(sncpf_device);
+      out_platform_alloced:
+	platform_device_put(sncpf_device);
+      out_platform_registered:
+	platform_driver_unregister(&sncpf_driver);
+      out:
+	return ret;
+}
+
+static void sony_snc_pf_remove(void)
+{
+	struct sony_acpi_value *item;
+
+	for (item = sony_acpi_values; item->name; ++item) {
+		device_remove_file(&sncpf_device->dev, &item->devattr);
+	}
+
+	platform_device_del(sncpf_device);
+	platform_device_put(sncpf_device);
+	platform_driver_unregister(&sncpf_driver);
+}
+
+/*
+ * Backlight device
+ */
+static int sony_backlight_update_status(struct backlight_device *bd)
+{
+	return acpi_callsetfunc(sony_acpi_handle, "SBRT",
+				bd->props->brightness + 1, NULL);
+}
+
+static int sony_backlight_get_brightness(struct backlight_device *bd)
+{
+	int value;
+
+	if (acpi_callgetfunc(sony_acpi_handle, "GBRT", &value))
+		return 0;
+	/* brightness levels are 1-based, while backlight ones are 0-based */
+	return value - 1;
+}
+
+static struct backlight_device *sony_backlight_device;
+static struct backlight_properties sony_backlight_properties = {
+	.owner = THIS_MODULE,
+	.update_status = sony_backlight_update_status,
+	.get_brightness = sony_backlight_get_brightness,
+	.max_brightness = SONY_MAX_BRIGHTNESS - 1,
+};
+
+/*
+ * ACPI callbacks
+ */
+static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
+{
+	if (debug)
+		printk(LOG_PFX "sony_acpi_notify, event: %d\n", event);
+	acpi_bus_generate_event(sony_acpi_acpi_device, 1, event);
+}
+
+static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
+				      void *context, void **return_value)
+{
+	struct acpi_namespace_node *node;
+	union acpi_operand_object *operand;
+
+	node = (struct acpi_namespace_node *)handle;
+	operand = (union acpi_operand_object *)node->object;
+
+	printk(LOG_PFX "method: name: %4.4s, args %X\n", node->name.ascii,
+	       (u32) operand->method.param_count);
+
+	return AE_OK;
+}
+
+/*
+ * ACPI device
+ */
+static int sony_acpi_resume(struct acpi_device *device)
+{
+	struct sony_acpi_value *item;
+
+	for (item = sony_acpi_values; item->name; item++) {
+		int ret;
+
+		if (!item->valid)
+			continue;
+		ret = acpi_callsetfunc(sony_acpi_handle, *item->acpiset,
+				       item->value, NULL);
+		if (ret < 0) {
+			printk("%s: %d\n", __FUNCTION__, ret);
+			break;
+		}
+	}
+	return 0;
+}
+
+static int sony_acpi_add(struct acpi_device *device)
+{
+	acpi_status status;
+	int result;
+	acpi_handle handle;
+
+	sony_acpi_acpi_device = device;
+
+	sony_acpi_handle = device->handle;
+
+	if (debug) {
+		status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_acpi_handle,
+					     1, sony_walk_callback, NULL, NULL);
+		if (ACPI_FAILURE(status)) {
+			printk(LOG_PFX "unable to walk acpi resources\n");
+			result = -ENODEV;
+			goto outwalk;
+		}
+	}
+
+	status = acpi_install_notify_handler(sony_acpi_handle,
+					     ACPI_DEVICE_NOTIFY,
+					     sony_acpi_notify, NULL);
+	if (ACPI_FAILURE(status)) {
+		printk(LOG_PFX "unable to install notify handler\n");
+		result = -ENODEV;
+		goto outwalk;
+	}
+
+	if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, "GBRT", &handle))) {
+		sony_backlight_device = backlight_device_register("sony", NULL,
+								  NULL,
+								  &sony_backlight_properties);
+
+		if (IS_ERR(sony_backlight_device)) {
+			printk(LOG_PFX "unable to register backlight device\n");
+			sony_backlight_device = NULL;
+		} else
+			sony_backlight_properties.brightness =
+			    sony_backlight_get_brightness
+			    (sony_backlight_device);
+	}
+
+	if (sony_snc_pf_add())
+		goto outbacklight;
+
+	printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully installed\n");
+
+	return 0;
+
+      outbacklight:
+	if (sony_backlight_device)
+		backlight_device_unregister(sony_backlight_device);
+
+	status = acpi_remove_notify_handler(sony_acpi_handle,
+					    ACPI_DEVICE_NOTIFY,
+					    sony_acpi_notify);
+	if (ACPI_FAILURE(status))
+		printk(LOG_PFX "unable to remove notify handler\n");
+      outwalk:
+	return result;
+}
+
+static int sony_acpi_remove(struct acpi_device *device, int type)
+{
+	acpi_status status;
+
+	if (sony_backlight_device)
+		backlight_device_unregister(sony_backlight_device);
+
+	sony_acpi_acpi_device = NULL;
+
+	status = acpi_remove_notify_handler(sony_acpi_handle,
+					    ACPI_DEVICE_NOTIFY,
+					    sony_acpi_notify);
+	if (ACPI_FAILURE(status))
+		printk(LOG_PFX "unable to remove notify handler\n");
+
+	sony_snc_pf_remove();
+
+	printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully removed\n");
+
+	return 0;
+}
+
+static struct acpi_driver sony_acpi_driver = {
+	.name = ACPI_SNC_DRIVER_NAME,
+	.class = ACPI_SNC_CLASS,
+	.ids = ACPI_SNC_HID,
+	.ops = {
+		.add = sony_acpi_add,
+		.remove = sony_acpi_remove,
+		.resume = sony_acpi_resume,
+		},
+};
+
+static int __init sony_acpi_init(void)
+{
+	return acpi_bus_register_driver(&sony_acpi_driver);
+}
+
+static void __exit sony_acpi_exit(void)
+{
+	acpi_bus_unregister_driver(&sony_acpi_driver);
+}
+
+module_init(sony_acpi_init);
+module_exit(sony_acpi_exit);
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c
index 2ce50f3..459f4b4 100644
--- a/drivers/mmc/at91_mci.c
+++ b/drivers/mmc/at91_mci.c
@@ -64,6 +64,7 @@
 #include <linux/err.h>
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
+#include <linux/atmel_pdc.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/protocol.h>
@@ -75,7 +76,6 @@
 #include <asm/arch/cpu.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/at91_mci.h>
-#include <asm/arch/at91_pdc.h>
 
 #define DRIVER_NAME "at91_mci"
 
@@ -211,13 +211,13 @@
 
 		/* Check to see if this needs filling */
 		if (i == 0) {
-			if (at91_mci_read(host, AT91_PDC_RCR) != 0) {
+			if (at91_mci_read(host, ATMEL_PDC_RCR) != 0) {
 				pr_debug("Transfer active in current\n");
 				continue;
 			}
 		}
 		else {
-			if (at91_mci_read(host, AT91_PDC_RNCR) != 0) {
+			if (at91_mci_read(host, ATMEL_PDC_RNCR) != 0) {
 				pr_debug("Transfer active in next\n");
 				continue;
 			}
@@ -234,12 +234,12 @@
 		pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length);
 
 		if (i == 0) {
-			at91_mci_write(host, AT91_PDC_RPR, sg->dma_address);
-			at91_mci_write(host, AT91_PDC_RCR, sg->length / 4);
+			at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address);
+			at91_mci_write(host, ATMEL_PDC_RCR, sg->length / 4);
 		}
 		else {
-			at91_mci_write(host, AT91_PDC_RNPR, sg->dma_address);
-			at91_mci_write(host, AT91_PDC_RNCR, sg->length / 4);
+			at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address);
+			at91_mci_write(host, ATMEL_PDC_RNCR, sg->length / 4);
 		}
 	}
 
@@ -303,7 +303,7 @@
 		at91mci_pre_dma_read(host);
 	else {
 		at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
-		at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS);
+		at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
 	}
 
 	pr_debug("post dma read done\n");
@@ -320,7 +320,7 @@
 	pr_debug("Handling the transmit\n");
 
 	/* Disable the transfer */
-	at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS);
+	at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
 
 	/* Now wait for cmd ready */
 	at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_TXBUFE);
@@ -431,15 +431,15 @@
 		cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(host, AT91_MCI_MR));
 
 	if (!data) {
-		at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_TXTDIS | AT91_PDC_RXTDIS);
-		at91_mci_write(host, AT91_PDC_RPR, 0);
-		at91_mci_write(host, AT91_PDC_RCR, 0);
-		at91_mci_write(host, AT91_PDC_RNPR, 0);
-		at91_mci_write(host, AT91_PDC_RNCR, 0);
-		at91_mci_write(host, AT91_PDC_TPR, 0);
-		at91_mci_write(host, AT91_PDC_TCR, 0);
-		at91_mci_write(host, AT91_PDC_TNPR, 0);
-		at91_mci_write(host, AT91_PDC_TNCR, 0);
+		at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS | ATMEL_PDC_RXTDIS);
+		at91_mci_write(host, ATMEL_PDC_RPR, 0);
+		at91_mci_write(host, ATMEL_PDC_RCR, 0);
+		at91_mci_write(host, ATMEL_PDC_RNPR, 0);
+		at91_mci_write(host, ATMEL_PDC_RNCR, 0);
+		at91_mci_write(host, ATMEL_PDC_TPR, 0);
+		at91_mci_write(host, ATMEL_PDC_TCR, 0);
+		at91_mci_write(host, ATMEL_PDC_TNPR, 0);
+		at91_mci_write(host, ATMEL_PDC_TNCR, 0);
 
 		at91_mci_write(host, AT91_MCI_ARGR, cmd->arg);
 		at91_mci_write(host, AT91_MCI_CMDR, cmdr);
@@ -452,7 +452,7 @@
 	/*
 	 * Disable the PDC controller
 	 */
-	at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS);
+	at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
 
 	if (cmdr & AT91_MCI_TRCMD_START) {
 		data->bytes_xfered = 0;
@@ -481,8 +481,8 @@
 
 			pr_debug("Transmitting %d bytes\n", host->total_length);
 
-			at91_mci_write(host, AT91_PDC_TPR, host->physical_address);
-			at91_mci_write(host, AT91_PDC_TCR, host->total_length / 4);
+			at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
+			at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4);
 			ier = AT91_MCI_TXBUFE;
 		}
 	}
@@ -497,9 +497,9 @@
 
 	if (cmdr & AT91_MCI_TRCMD_START) {
 		if (cmdr & AT91_MCI_TRDIR)
-			at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTEN);
+			at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);
 		else
-			at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_TXTEN);
+			at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
 	}
 	return ier;
 }
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index f69184a..f334959 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -397,9 +397,23 @@
 	cfi_fixup(mtd, fixup_table);
 
 	for (i=0; i< cfi->numchips; i++) {
-		cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
-		cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
-		cfi->chips[i].erase_time = 1000<<cfi->cfiq->BlockEraseTimeoutTyp;
+		if (cfi->cfiq->WordWriteTimeoutTyp)
+			cfi->chips[i].word_write_time =
+				1<<cfi->cfiq->WordWriteTimeoutTyp;
+		else
+			cfi->chips[i].word_write_time = 50000;
+
+		if (cfi->cfiq->BufWriteTimeoutTyp)
+			cfi->chips[i].buffer_write_time =
+				1<<cfi->cfiq->BufWriteTimeoutTyp;
+		/* No default; if it isn't specified, we won't use it */
+
+		if (cfi->cfiq->BlockEraseTimeoutTyp)
+			cfi->chips[i].erase_time =
+				1000<<cfi->cfiq->BlockEraseTimeoutTyp;
+		else
+			cfi->chips[i].erase_time = 2000000;
+
 		cfi->chips[i].ref_point_counter = 0;
 		init_waitqueue_head(&(cfi->chips[i].wq));
 	}
@@ -546,13 +560,11 @@
 			struct cfi_intelext_programming_regioninfo *prinfo;
 			prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs];
 			mtd->writesize = cfi->interleave << prinfo->ProgRegShift;
-			MTD_PROGREGION_CTRLMODE_VALID(mtd) = cfi->interleave * prinfo->ControlValid;
-			MTD_PROGREGION_CTRLMODE_INVALID(mtd) = cfi->interleave * prinfo->ControlInvalid;
 			mtd->flags &= ~MTD_BIT_WRITEABLE;
 			printk(KERN_DEBUG "%s: program region size/ctrl_valid/ctrl_inval = %d/%d/%d\n",
 			       map->name, mtd->writesize,
-			       MTD_PROGREGION_CTRLMODE_VALID(mtd),
-			       MTD_PROGREGION_CTRLMODE_INVALID(mtd));
+			       cfi->interleave * prinfo->ControlValid,
+			       cfi->interleave * prinfo->ControlInvalid);
 		}
 
 		/*
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index d56849f..69d49e0 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -662,7 +662,7 @@
  * a small buffer for this.
  * XXX: If the buffer size is not a multiple of 2, this will break
  */
-#define ECCBUF_SIZE (mtd->eccsize)
+#define ECCBUF_SIZE (mtd->writesize)
 #define ECCBUF_DIV(x) ((x) & ~(ECCBUF_SIZE - 1))
 #define ECCBUF_MOD(x) ((x) &  (ECCBUF_SIZE - 1))
 static int
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 603a795..8a0c4de 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -569,7 +569,6 @@
 
 	mtd->type = MTD_NANDFLASH;
 	mtd->flags = MTD_CAP_NANDFLASH;
-	mtd->ecctype = MTD_ECC_RS_DiskOnChip;
 	mtd->size = 0;
 	mtd->erasesize = 0;
 	mtd->writesize = 512;
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index fe71a12..6f368ae 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -348,7 +348,6 @@
 
 	mtd->type = MTD_NANDFLASH;
 	mtd->flags = MTD_CAP_NANDFLASH;
-	mtd->ecctype = MTD_ECC_RS_DiskOnChip;
 	mtd->size = 0;
 
 	/* FIXME: erase size is not always 8KiB */
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index ba4db68..88ba82d 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -472,7 +472,6 @@
 
 	mtd->type = MTD_NANDFLASH;
 	mtd->flags = MTD_CAP_NANDFLASH;
-	mtd->ecctype = MTD_ECC_RS_DiskOnChip;
 	mtd->size = 0;
 
 	mtd->erasesize = 0;
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index f457315..bbf0553 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -204,7 +204,7 @@
 
 config MTD_CK804XROM
 	tristate "BIOS flash chip on Nvidia CK804"
-	depends on X86 && MTD_JEDECPROBE
+	depends on X86 && MTD_JEDECPROBE && PCI
 	help
 	  Support for treating the BIOS flash chip on nvidia motherboards
 	  as an MTD device - with this you can reprogram your BIOS.
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c
index 78b6711..728aed6 100644
--- a/drivers/mtd/maps/amd76xrom.c
+++ b/drivers/mtd/maps/amd76xrom.c
@@ -205,8 +205,8 @@
 			(((unsigned long)(window->virt)) + offset);
 		map->map.size = 0xffffffffUL - map_top + 1UL;
 		/* Set the name of the map to the address I am trying */
-		sprintf(map->map_name, "%s @%08lx",
-			MOD_NAME, map->map.phys);
+		sprintf(map->map_name, "%s @%08Lx",
+			MOD_NAME, (unsigned long long)map->map.phys);
 
 		/* There is no generic VPP support */
 		for(map->map.bankwidth = 32; map->map.bankwidth;
diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c
index 238d42e..3d4a4d8 100644
--- a/drivers/mtd/maps/ck804xrom.c
+++ b/drivers/mtd/maps/ck804xrom.c
@@ -207,8 +207,8 @@
 			(((unsigned long)(window->virt)) + offset);
 		map->map.size = 0xffffffffUL - map_top + 1UL;
 		/* Set the name of the map to the address I am trying */
-		sprintf(map->map_name, "%s @%08lx",
-			MOD_NAME, map->map.phys);
+		sprintf(map->map_name, "%s @%08Lx",
+			MOD_NAME, (unsigned long long)map->map.phys);
 
 		/* There is no generic VPP support */
 		for(map->map.bankwidth = 32; map->map.bankwidth;
@@ -327,7 +327,7 @@
 	pdev = NULL;
 
 	for(id = ck804xrom_pci_tbl; id->vendor; id++) {
-		pdev = pci_find_device(id->vendor, id->device, NULL);
+		pdev = pci_get_device(id->vendor, id->device, NULL);
 		if (pdev)
 			break;
 	}
diff --git a/drivers/mtd/maps/esb2rom.c b/drivers/mtd/maps/esb2rom.c
index a9d808a..0bc013f 100644
--- a/drivers/mtd/maps/esb2rom.c
+++ b/drivers/mtd/maps/esb2rom.c
@@ -289,8 +289,8 @@
 			(((unsigned long)(window->virt)) + offset);
 		map->map.size = 0xffffffffUL - map_top + 1UL;
 		/* Set the name of the map to the address I am trying */
-		sprintf(map->map_name, "%s @%08lx",
-			MOD_NAME, map->map.phys);
+		sprintf(map->map_name, "%s @%08Lx",
+			MOD_NAME, (unsigned long long)map->map.phys);
 
 		/* Firmware hubs only use vpp when being programmed
 		 * in a factory setting.  So in-place programming
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
index 2bb3e63..2c884c4 100644
--- a/drivers/mtd/maps/ichxrom.c
+++ b/drivers/mtd/maps/ichxrom.c
@@ -227,8 +227,8 @@
 			(((unsigned long)(window->virt)) + offset);
 		map->map.size = 0xffffffffUL - map_top + 1UL;
 		/* Set the name of the map to the address I am trying */
-		sprintf(map->map_name, "%s @%08lx",
-			MOD_NAME, map->map.phys);
+		sprintf(map->map_name, "%s @%08Lx",
+			MOD_NAME, (unsigned long long)map->map.phys);
 
 		/* Firmware hubs only use vpp when being programmed
 		 * in a factory setting.  So in-place programming
diff --git a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c
index ed21547..95dcab2 100644
--- a/drivers/mtd/maps/netsc520.c
+++ b/drivers/mtd/maps/netsc520.c
@@ -94,7 +94,9 @@
 
 static int __init init_netsc520(void)
 {
-	printk(KERN_NOTICE "NetSc520 flash device: 0x%lx at 0x%lx\n", netsc520_map.size, netsc520_map.phys);
+	printk(KERN_NOTICE "NetSc520 flash device: 0x%Lx at 0x%Lx\n",
+			(unsigned long long)netsc520_map.size,
+			(unsigned long long)netsc520_map.phys);
 	netsc520_map.virt = ioremap_nocache(netsc520_map.phys, netsc520_map.size);
 
 	if (!netsc520_map.virt) {
diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c
index 9b50cfc..4045e37 100644
--- a/drivers/mtd/maps/sc520cdp.c
+++ b/drivers/mtd/maps/sc520cdp.c
@@ -237,8 +237,9 @@
 #endif
 
 	for (i = 0; i < NUM_FLASH_BANKS; i++) {
-		printk(KERN_NOTICE "SC520 CDP flash device: 0x%lx at 0x%lx\n",
-		       sc520cdp_map[i].size, sc520cdp_map[i].phys);
+		printk(KERN_NOTICE "SC520 CDP flash device: 0x%Lx at 0x%Lx\n",
+			(unsigned long long)sc520cdp_map[i].size,
+			(unsigned long long)sc520cdp_map[i].phys);
 
 		sc520cdp_map[i].virt = ioremap_nocache(sc520cdp_map[i].phys, sc520cdp_map[i].size);
 
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 61a994e..1592eac 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -419,8 +419,9 @@
 		info.erasesize	= mtd->erasesize;
 		info.writesize	= mtd->writesize;
 		info.oobsize	= mtd->oobsize;
-		info.ecctype	= mtd->ecctype;
-		info.eccsize	= mtd->eccsize;
+		/* The below fields are obsolete */
+		info.ecctype	= -1;
+		info.eccsize	= 0;
 		if (copy_to_user(argp, &info, sizeof(struct mtd_info_user)))
 			return -EFAULT;
 		break;
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 0690268..880580c 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -727,8 +727,6 @@
 	concat->mtd.erasesize = subdev[0]->erasesize;
 	concat->mtd.writesize = subdev[0]->writesize;
 	concat->mtd.oobsize = subdev[0]->oobsize;
-	concat->mtd.ecctype = subdev[0]->ecctype;
-	concat->mtd.eccsize = subdev[0]->eccsize;
 	if (subdev[0]->writev)
 		concat->mtd.writev = concat_writev;
 	if (subdev[0]->read_oob)
@@ -774,8 +772,6 @@
 		if (concat->mtd.writesize   !=  subdev[i]->writesize ||
 		    concat->mtd.subpage_sft != subdev[i]->subpage_sft ||
 		    concat->mtd.oobsize    !=  subdev[i]->oobsize ||
-		    concat->mtd.ecctype    !=  subdev[i]->ecctype ||
-		    concat->mtd.eccsize    !=  subdev[i]->eccsize ||
 		    !concat->mtd.read_oob  != !subdev[i]->read_oob ||
 		    !concat->mtd.write_oob != !subdev[i]->write_oob) {
 			kfree(concat);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index bafd2fb..633def3 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -338,8 +338,6 @@
 		slave->mtd.size = parts[i].size;
 		slave->mtd.writesize = master->writesize;
 		slave->mtd.oobsize = master->oobsize;
-		slave->mtd.ecctype = master->ecctype;
-		slave->mtd.eccsize = master->eccsize;
 		slave->mtd.subpage_sft = master->subpage_sft;
 
 		slave->mtd.name = parts[i].name;
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 358f55a..2d12dcd 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -126,10 +126,6 @@
 	  incorrect ECC generation, and if using these, the default of
 	  software ECC is preferable.
 
-	  If you lay down a device with the hardware ECC, then you will
-	  currently not be able to switch to software, as there is no
-	  implementation for ECC method used by the S3C2410
-
 config MTD_NAND_NDFC
 	tristate "NDFC NanD Flash Controller"
 	depends on MTD_NAND && 44x
@@ -221,9 +217,17 @@
 	tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
 	depends on MTD_NAND && ARCH_PXA
 
+config MTD_NAND_BASLER_EXCITE
+	tristate  "Support for NAND Flash on Basler eXcite"
+	depends on MTD_NAND && BASLER_EXCITE
+	help
+          This enables the driver for the NAND flash device found on the
+          Basler eXcite Smart Camera. If built as a module, the driver
+          will be named "excite_nandflash.ko".
+
 config MTD_NAND_CAFE
        tristate "NAND support for OLPC CAFÉ chip"
-       depends on PCI
+       depends on MTD_NAND && PCI
        help
 	 Use NAND flash attached to the CAFÉ chip designed for the $100
 	 laptop.
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index f7a53f0..80f1dfc 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -24,6 +24,7 @@
 obj-$(CONFIG_MTD_NAND_CS553X)		+= cs553x_nand.o
 obj-$(CONFIG_MTD_NAND_NDFC)		+= ndfc.o
 obj-$(CONFIG_MTD_NAND_AT91)		+= at91_nand.o
+obj-$(CONFIG_MTD_NAND_BASLER_EXCITE)	+= excite_nandflash.o
 
 nand-objs := nand_base.o nand_bbt.o
 cafe_nand-objs := cafe.o cafe_ecc.o
diff --git a/drivers/mtd/nand/cafe.c b/drivers/mtd/nand/cafe.c
index 08cb060..fd6bb3e 100644
--- a/drivers/mtd/nand/cafe.c
+++ b/drivers/mtd/nand/cafe.c
@@ -78,8 +78,9 @@
 static int checkecc = 1;
 module_param(checkecc, int, 0644);
 
-static int slowtiming = 0;
-module_param(slowtiming, int, 0644);
+static int numtimings;
+static int timing[3];
+module_param_array(timing, int, &numtimings, 0644);
 
 /* Hrm. Why isn't this already conditional on something in the struct device? */
 #define cafe_dev_dbg(dev, args...) do { if (debug) dev_dbg(dev, ##args); } while(0)
@@ -264,10 +265,10 @@
 	ndelay(100);
 
 	if (1) {
-		int c = 500000;
+		int c;
 		uint32_t irqs;
 
-		while (c--) {
+		for (c = 500000; c != 0; c--) {
 			irqs = cafe_readl(cafe, NAND_IRQ);
 			if (irqs & doneint)
 				break;
@@ -529,6 +530,7 @@
 {
 	struct mtd_info *mtd;
 	struct cafe_priv *cafe;
+	uint32_t timing1, timing2, timing3;
 	uint32_t ctrl;
 	int err = 0;
 
@@ -580,31 +582,45 @@
 		cafe->nand.block_bad = cafe_nand_block_bad;
 	}
 
+	if (numtimings && numtimings != 3) {
+		dev_warn(&cafe->pdev->dev, "%d timing register values ignored; precisely three are required\n", numtimings);
+	}
+
+	if (numtimings == 3) {
+		timing1 = timing[0];
+		timing2 = timing[1];
+		timing3 = timing[2];
+		cafe_dev_dbg(&cafe->pdev->dev, "Using provided timings (%08x %08x %08x)\n",
+			     timing1, timing2, timing3);
+	} else {
+		timing1 = cafe_readl(cafe, NAND_TIMING1);
+		timing2 = cafe_readl(cafe, NAND_TIMING2);
+		timing3 = cafe_readl(cafe, NAND_TIMING3);
+
+		if (timing1 | timing2 | timing3) {
+			cafe_dev_dbg(&cafe->pdev->dev, "Timing registers already set (%08x %08x %08x)\n", timing1, timing2, timing3);
+		} else {
+			dev_warn(&cafe->pdev->dev, "Timing registers unset; using most conservative defaults\n");
+			timing1 = timing2 = timing3 = 0xffffffff;
+		}
+	}
+
 	/* Start off by resetting the NAND controller completely */
 	cafe_writel(cafe, 1, NAND_RESET);
 	cafe_writel(cafe, 0, NAND_RESET);
 
-	cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK);
+	cafe_writel(cafe, timing1, NAND_TIMING1);
+	cafe_writel(cafe, timing2, NAND_TIMING2);
+	cafe_writel(cafe, timing3, NAND_TIMING3);
 
-	/* Timings from Marvell's test code (not verified or calculated by us) */
-	if (!slowtiming) {
-		cafe_writel(cafe, 0x01010a0a, NAND_TIMING1);
-		cafe_writel(cafe, 0x24121212, NAND_TIMING2);
-		cafe_writel(cafe, 0x11000000, NAND_TIMING3);
-	} else {
-		cafe_writel(cafe, 0xffffffff, NAND_TIMING1);
-		cafe_writel(cafe, 0xffffffff, NAND_TIMING2);
-		cafe_writel(cafe, 0xffffffff, NAND_TIMING3);
-	}
 	cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK);
 	err = request_irq(pdev->irq, &cafe_nand_interrupt, IRQF_SHARED,
 			  "CAFE NAND", mtd);
 	if (err) {
 		dev_warn(&pdev->dev, "Could not register IRQ %d\n", pdev->irq);
-
 		goto out_free_dma;
 	}
-#if 1
+
 	/* Disable master reset, enable NAND clock */
 	ctrl = cafe_readl(cafe, GLOBAL_CTRL);
 	ctrl &= 0xffffeff0;
@@ -631,32 +647,8 @@
 	cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK);
 	cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n",
 		cafe_readl(cafe, GLOBAL_CTRL), cafe_readl(cafe, GLOBAL_IRQ_MASK));
-#endif
-#if 1
-	mtd->writesize=2048;
-	mtd->oobsize = 0x40;
-	memset(cafe->dmabuf, 0x5a, 2112);
-	cafe->nand.cmdfunc(mtd, NAND_CMD_READID, 0, -1);
-	cafe->nand.read_byte(mtd);
-	cafe->nand.read_byte(mtd);
-	cafe->nand.read_byte(mtd);
-	cafe->nand.read_byte(mtd);
-	cafe->nand.read_byte(mtd);
-#endif
-#if 0
-	cafe->nand.cmdfunc(mtd, NAND_CMD_READ0, 0, 0);
-	//	nand_wait_ready(mtd);
-	cafe->nand.read_byte(mtd);
-	cafe->nand.read_byte(mtd);
-	cafe->nand.read_byte(mtd);
-	cafe->nand.read_byte(mtd);
-#endif
-#if 0
-	writel(0x84600070, cafe->mmio);
-	udelay(10);
-	cafe_dev_dbg(&cafe->pdev->dev, "Status %x\n", cafe_readl(cafe, NAND_NONMEM));
-#endif
-	/* Scan to find existance of the device */
+
+	/* Scan to find existence of the device */
 	if (nand_scan_ident(mtd, 1)) {
 		err = -ENXIO;
 		goto out_irq;
@@ -760,13 +752,4 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("NAND flash driver for OLPC CAFE chip");
-
-/* Correct ECC for 2048 bytes of 0xff:
-   41 a0 71 65 54 27 f3 93 ec a9 be ed 0b a1 */
-
-/* dwmw2's B-test board, in case of completely screwing it:
-Bad eraseblock 2394 at 0x12b40000
-Bad eraseblock 2627 at 0x14860000
-Bad eraseblock 3349 at 0x1a2a0000
-*/
+MODULE_DESCRIPTION("NAND flash driver for OLPC CAFÉ chip");
diff --git a/drivers/mtd/nand/cafe_ecc.c b/drivers/mtd/nand/cafe_ecc.c
index 1b9fa05..ea5c849 100644
--- a/drivers/mtd/nand/cafe_ecc.c
+++ b/drivers/mtd/nand/cafe_ecc.c
@@ -1045,7 +1045,7 @@
 
 static unsigned short err_pos(unsigned short din)
 {
-	BUG_ON(din > 4096);
+	BUG_ON(din >= ARRAY_SIZE(err_pos_lut));
 	return err_pos_lut[din];
 }
 static int chk_no_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info)
diff --git a/drivers/mtd/nand/excite_nandflash.c b/drivers/mtd/nand/excite_nandflash.c
new file mode 100644
index 0000000..7e9afc4
--- /dev/null
+++ b/drivers/mtd/nand/excite_nandflash.c
@@ -0,0 +1,248 @@
+/*
+*  Copyright (C) 2005 - 2007 by Basler Vision Technologies AG
+*  Author: Thomas Koeller <thomas.koeller.qbaslerweb.com>
+*  Original code by Thies Moeller <thies.moeller@baslerweb.com>
+*
+*  This program is free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  This program is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  You should have received a copy of the GNU General Public License
+*  along with this program; if not, write to the Free Software
+*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+#include <asm/rm9k-ocd.h>
+
+#include <excite_nandflash.h>
+
+#define EXCITE_NANDFLASH_VERSION "0.1"
+
+/* I/O register offsets */
+#define EXCITE_NANDFLASH_DATA_BYTE   0x00
+#define EXCITE_NANDFLASH_STATUS_BYTE 0x0c
+#define EXCITE_NANDFLASH_ADDR_BYTE   0x10
+#define EXCITE_NANDFLASH_CMD_BYTE    0x14
+
+/* prefix for debug output */
+static const char module_id[] = "excite_nandflash";
+
+/*
+ * partition definition
+ */
+static const struct mtd_partition partition_info[] = {
+	{
+		.name = "eXcite RootFS",
+		.offset = 0,
+		.size = MTDPART_SIZ_FULL
+	}
+};
+
+static inline const struct resource *
+excite_nand_get_resource(struct platform_device *d, unsigned long flags,
+			 const char *basename)
+{
+	char buf[80];
+
+	if (snprintf(buf, sizeof buf, "%s_%u", basename, d->id) >= sizeof buf)
+		return NULL;
+	return platform_get_resource_byname(d, flags, buf);
+}
+
+static inline void __iomem *
+excite_nand_map_regs(struct platform_device *d, const char *basename)
+{
+	void *result = NULL;
+	const struct resource *const r =
+	    excite_nand_get_resource(d, IORESOURCE_MEM, basename);
+
+	if (r)
+		result = ioremap_nocache(r->start, r->end + 1 - r->start);
+	return result;
+}
+
+/* controller and mtd information */
+struct excite_nand_drvdata {
+	struct mtd_info board_mtd;
+	struct nand_chip board_chip;
+	void __iomem *regs;
+	void __iomem *tgt;
+};
+
+/* Control function */
+static void excite_nand_control(struct mtd_info *mtd, int cmd,
+				       unsigned int ctrl)
+{
+	struct excite_nand_drvdata * const d =
+	    container_of(mtd, struct excite_nand_drvdata, board_mtd);
+
+	switch (ctrl) {
+	case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
+		d->tgt = d->regs + EXCITE_NANDFLASH_CMD_BYTE;
+		break;
+	case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
+		d->tgt = d->regs + EXCITE_NANDFLASH_ADDR_BYTE;
+		break;
+	case NAND_CTRL_CHANGE | NAND_NCE:
+		d->tgt = d->regs + EXCITE_NANDFLASH_DATA_BYTE;
+		break;
+	}
+
+	if (cmd != NAND_CMD_NONE)
+		__raw_writeb(cmd, d->tgt);
+}
+
+/* Return 0 if flash is busy, 1 if ready */
+static int excite_nand_devready(struct mtd_info *mtd)
+{
+	struct excite_nand_drvdata * const drvdata =
+	    container_of(mtd, struct excite_nand_drvdata, board_mtd);
+
+	return __raw_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS_BYTE);
+}
+
+/*
+ * Called by device layer to remove the driver.
+ * The binding to the mtd and all allocated
+ * resources are released.
+ */
+static int __exit excite_nand_remove(struct device *dev)
+{
+	struct excite_nand_drvdata * const this = dev_get_drvdata(dev);
+
+	dev_set_drvdata(dev, NULL);
+
+	if (unlikely(!this)) {
+		printk(KERN_ERR "%s: called %s without private data!!",
+		       module_id, __func__);
+		return -EINVAL;
+	}
+
+	/* first thing we need to do is release our mtd
+	 * then go through freeing the resource used
+	 */
+	nand_release(&this->board_mtd);
+
+	/* free the common resources */
+	iounmap(this->regs);
+	kfree(this);
+
+	DEBUG(MTD_DEBUG_LEVEL1, "%s: removed\n", module_id);
+	return 0;
+}
+
+/*
+ * Called by device layer when it finds a device matching
+ * one our driver can handle. This code checks to see if
+ * it can allocate all necessary resources then calls the
+ * nand layer to look for devices.
+*/
+static int __init excite_nand_probe(struct device *dev)
+{
+	struct platform_device * const pdev = to_platform_device(dev);
+	struct excite_nand_drvdata *drvdata;	/* private driver data */
+	struct nand_chip *board_chip;	/* private flash chip data */
+	struct mtd_info *board_mtd;	/* mtd info for this board */
+	int scan_res;
+
+	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+	if (unlikely(!drvdata)) {
+		printk(KERN_ERR "%s: no memory for drvdata\n",
+		       module_id);
+		return -ENOMEM;
+	}
+
+	/* bind private data into driver */
+	dev_set_drvdata(dev, drvdata);
+
+	/* allocate and map the resource */
+	drvdata->regs =
+		excite_nand_map_regs(pdev, EXCITE_NANDFLASH_RESOURCE_REGS);
+
+	if (unlikely(!drvdata->regs)) {
+		printk(KERN_ERR "%s: cannot reserve register region\n",
+		       module_id);
+		kfree(drvdata);
+		return -ENXIO;
+	}
+	
+	drvdata->tgt = drvdata->regs + EXCITE_NANDFLASH_DATA_BYTE;
+
+	/* initialise our chip */
+	board_chip = &drvdata->board_chip;
+	board_chip->IO_ADDR_R = board_chip->IO_ADDR_W =
+		drvdata->regs + EXCITE_NANDFLASH_DATA_BYTE;
+	board_chip->cmd_ctrl = excite_nand_control;
+	board_chip->dev_ready = excite_nand_devready;
+	board_chip->chip_delay = 25;
+	board_chip->ecc.mode = NAND_ECC_SOFT;
+
+	/* link chip to mtd */
+	board_mtd = &drvdata->board_mtd;
+	board_mtd->priv = board_chip;
+
+	DEBUG(MTD_DEBUG_LEVEL2, "%s: device scan\n", module_id);
+	scan_res = nand_scan(&drvdata->board_mtd, 1);
+
+	if (likely(!scan_res)) {
+		DEBUG(MTD_DEBUG_LEVEL2, "%s: register partitions\n", module_id);
+		add_mtd_partitions(&drvdata->board_mtd, partition_info,
+				   sizeof partition_info / sizeof partition_info[0]);
+	} else {
+		iounmap(drvdata->regs);
+		kfree(drvdata);
+		printk(KERN_ERR "%s: device scan failed\n", module_id);
+		return -EIO;
+	}
+	return 0;
+}
+
+static struct device_driver excite_nand_driver = {
+	.name = "excite_nand",
+	.bus = &platform_bus_type,
+	.probe = excite_nand_probe,
+	.remove = __exit_p(excite_nand_remove)
+};
+
+static int __init excite_nand_init(void)
+{
+	pr_info("Basler eXcite nand flash driver Version "
+		EXCITE_NANDFLASH_VERSION "\n");
+	return driver_register(&excite_nand_driver);
+}
+
+static void __exit excite_nand_exit(void)
+{
+	driver_unregister(&excite_nand_driver);
+}
+
+module_init(excite_nand_init);
+module_exit(excite_nand_exit);
+
+MODULE_AUTHOR("Thomas Koeller <thomas.koeller@baslerweb.com>");
+MODULE_DESCRIPTION("Basler eXcite NAND-Flash driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(EXCITE_NANDFLASH_VERSION)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index dfe56e0..acaf97b 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1272,10 +1272,25 @@
 	DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n",
 	      (unsigned long long)from, readlen);
 
-	if (ops->mode == MTD_OOB_RAW)
-		len = mtd->oobsize;
-	else
+	if (ops->mode == MTD_OOB_AUTO)
 		len = chip->ecc.layout->oobavail;
+	else
+		len = mtd->oobsize;
+
+	if (unlikely(ops->ooboffs >= len)) {
+		DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+			"Attempt to start read outside oob\n");
+		return -EINVAL;
+	}
+
+	/* Do not allow reads past end of device */
+	if (unlikely(from >= mtd->size ||
+		     ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) -
+					(from >> chip->page_shift)) * len)) {
+		DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+			"Attempt read beyond end of device\n");
+		return -EINVAL;
+	}
 
 	chipnr = (int)(from >> chip->chip_shift);
 	chip->select_chip(mtd, chipnr);
@@ -1742,19 +1757,40 @@
 static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 			     struct mtd_oob_ops *ops)
 {
-	int chipnr, page, status;
+	int chipnr, page, status, len;
 	struct nand_chip *chip = mtd->priv;
 
 	DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n",
 	      (unsigned int)to, (int)ops->ooblen);
 
+	if (ops->mode == MTD_OOB_AUTO)
+		len = chip->ecc.layout->oobavail;
+	else
+		len = mtd->oobsize;
+
 	/* Do not allow write past end of page */
-	if ((ops->ooboffs + ops->ooblen) > mtd->oobsize) {
+	if ((ops->ooboffs + ops->ooblen) > len) {
 		DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
 		      "Attempt to write past end of page\n");
 		return -EINVAL;
 	}
 
+	if (unlikely(ops->ooboffs >= len)) {
+		DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+			"Attempt to start write outside oob\n");
+		return -EINVAL;
+	}
+
+	/* Do not allow reads past end of device */
+	if (unlikely(to >= mtd->size ||
+		     ops->ooboffs + ops->ooblen >
+			((mtd->size >> chip->page_shift) -
+			 (to >> chip->page_shift)) * len)) {
+		DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+			"Attempt write beyond end of device\n");
+		return -EINVAL;
+	}
+
 	chipnr = (int)(to >> chip->chip_shift);
 	chip->select_chip(mtd, chipnr);
 
@@ -2530,7 +2566,6 @@
 	/* Fill in remaining MTD driver data */
 	mtd->type = MTD_NANDFLASH;
 	mtd->flags = MTD_CAP_NANDFLASH;
-	mtd->ecctype = MTD_ECC_SW;
 	mtd->erase = nand_erase;
 	mtd->point = NULL;
 	mtd->unpoint = NULL;
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 8b32035..0ddfd6d 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -337,17 +337,69 @@
 static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
 				     u_char *read_ecc, u_char *calc_ecc)
 {
-	pr_debug("s3c2410_nand_correct_data(%p,%p,%p,%p)\n", mtd, dat, read_ecc, calc_ecc);
+	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+	unsigned int diff0, diff1, diff2;
+	unsigned int bit, byte;
 
-	pr_debug("eccs: read %02x,%02x,%02x vs calc %02x,%02x,%02x\n",
-		 read_ecc[0], read_ecc[1], read_ecc[2], calc_ecc[0], calc_ecc[1], calc_ecc[2]);
+	pr_debug("%s(%p,%p,%p,%p)\n", __func__, mtd, dat, read_ecc, calc_ecc);
 
-	if (read_ecc[0] == calc_ecc[0] && read_ecc[1] == calc_ecc[1] && read_ecc[2] == calc_ecc[2])
-		return 0;
+	diff0 = read_ecc[0] ^ calc_ecc[0];
+	diff1 = read_ecc[1] ^ calc_ecc[1];
+	diff2 = read_ecc[2] ^ calc_ecc[2];
 
-	/* we curently have no method for correcting the error */
+	pr_debug("%s: rd %02x%02x%02x calc %02x%02x%02x diff %02x%02x%02x\n",
+		 __func__,
+		 read_ecc[0], read_ecc[1], read_ecc[2],
+		 calc_ecc[0], calc_ecc[1], calc_ecc[2],
+		 diff0, diff1, diff2);
 
-	return -1;
+	if (diff0 == 0 && diff1 == 0 && diff2 == 0)
+		return 0;		/* ECC is ok */
+
+	/* Can we correct this ECC (ie, one row and column change).
+	 * Note, this is similar to the 256 error code on smartmedia */
+
+	if (((diff0 ^ (diff0 >> 1)) & 0x55) == 0x55 &&
+	    ((diff1 ^ (diff1 >> 1)) & 0x55) == 0x55 &&
+	    ((diff2 ^ (diff2 >> 1)) & 0x55) == 0x55) {
+		/* calculate the bit position of the error */
+
+		bit  = (diff2 >> 2) & 1;
+		bit |= (diff2 >> 3) & 2;
+		bit |= (diff2 >> 4) & 4;
+
+		/* calculate the byte position of the error */
+
+		byte  = (diff1 << 1) & 0x80;
+		byte |= (diff1 << 2) & 0x40;
+		byte |= (diff1 << 3) & 0x20;
+		byte |= (diff1 << 4) & 0x10;
+
+		byte |= (diff0 >> 3) & 0x08;
+		byte |= (diff0 >> 2) & 0x04;
+		byte |= (diff0 >> 1) & 0x02;
+		byte |= (diff0 >> 0) & 0x01;
+
+		byte |= (diff2 << 8) & 0x100;
+
+		dev_dbg(info->device, "correcting error bit %d, byte %d\n",
+			bit, byte);
+
+		dat[byte] ^= (1 << bit);
+		return 1;
+	}
+
+	/* if there is only one bit difference in the ECC, then
+	 * one of only a row or column parity has changed, which
+	 * means the error is most probably in the ECC itself */
+
+	diff0 |= (diff1 << 8);
+	diff0 |= (diff2 << 16);
+
+	if ((diff0 & ~(1<<fls(diff0))) == 0)
+		return 1;
+
+	return 0;
 }
 
 /* ECC functions
@@ -366,6 +418,15 @@
 	writel(ctrl, info->regs + S3C2410_NFCONF);
 }
 
+static void s3c2412_nand_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+	unsigned long ctrl;
+
+	ctrl = readl(info->regs + S3C2440_NFCONT);
+	writel(ctrl | S3C2412_NFCONT_INIT_MAIN_ECC, info->regs + S3C2440_NFCONT);
+}
+
 static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
 {
 	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
@@ -383,6 +444,21 @@
 	ecc_code[1] = readb(info->regs + S3C2410_NFECC + 1);
 	ecc_code[2] = readb(info->regs + S3C2410_NFECC + 2);
 
+	pr_debug("%s: returning ecc %02x%02x%02x\n", __func__,
+		 ecc_code[0], ecc_code[1], ecc_code[2]);
+
+	return 0;
+}
+
+static int s3c2412_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
+{
+	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+	unsigned long ecc = readl(info->regs + S3C2412_NFMECC0);
+
+	ecc_code[0] = ecc;
+	ecc_code[1] = ecc >> 8;
+	ecc_code[2] = ecc >> 16;
+
 	pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", ecc_code[0], ecc_code[1], ecc_code[2]);
 
 	return 0;
@@ -397,7 +473,7 @@
 	ecc_code[1] = ecc >> 8;
 	ecc_code[2] = ecc >> 16;
 
-	pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", ecc_code[0], ecc_code[1], ecc_code[2]);
+	pr_debug("%s: returning ecc %06x\n", __func__, ecc);
 
 	return 0;
 }
@@ -565,6 +641,10 @@
 			break;
 
 		case TYPE_S3C2412:
+  			chip->ecc.hwctl     = s3c2412_nand_enable_hwecc;
+  			chip->ecc.calculate = s3c2412_nand_calculate_ecc;
+			break;
+
 		case TYPE_S3C2440:
   			chip->ecc.hwctl     = s3c2440_nand_enable_hwecc;
   			chip->ecc.calculate = s3c2440_nand_calculate_ecc;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 2da6bb2..7f1cb6e 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1,7 +1,7 @@
 /*
  *  linux/drivers/mtd/onenand/onenand_base.c
  *
- *  Copyright (C) 2005-2006 Samsung Electronics
+ *  Copyright (C) 2005-2007 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -94,16 +94,9 @@
  */
 static int onenand_block_address(struct onenand_chip *this, int block)
 {
-	if (this->device_id & ONENAND_DEVICE_IS_DDP) {
-		/* Device Flash Core select, NAND Flash Block Address */
-		int dfs = 0;
-
-		if (block & this->density_mask)
-			dfs = 1;
-
-		return (dfs << ONENAND_DDP_SHIFT) |
-			(block & (this->density_mask - 1));
-	}
+	/* Device Flash Core select, NAND Flash Block Address */
+	if (block & this->density_mask)
+		return ONENAND_DDP_CHIP1 | (block ^ this->density_mask);
 
 	return block;
 }
@@ -118,17 +111,11 @@
  */
 static int onenand_bufferram_address(struct onenand_chip *this, int block)
 {
-	if (this->device_id & ONENAND_DEVICE_IS_DDP) {
-		/* Device BufferRAM Select */
-		int dbs = 0;
+	/* Device BufferRAM Select */
+	if (block & this->density_mask)
+		return ONENAND_DDP_CHIP1;
 
-		if (block & this->density_mask)
-			dbs = 1;
-
-		return (dbs << ONENAND_DDP_SHIFT);
-	}
-
-	return 0;
+	return ONENAND_DDP_CHIP0;
 }
 
 /**
@@ -317,22 +304,25 @@
 	ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
 
 	if (ctrl & ONENAND_CTRL_ERROR) {
-		DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl);
+		printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", ctrl);
 		if (ctrl & ONENAND_CTRL_LOCK)
-			DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error.\n");
+			printk(KERN_ERR "onenand_wait: it's locked error.\n");
 		return ctrl;
 	}
 
 	if (interrupt & ONENAND_INT_READ) {
 		int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
 		if (ecc) {
-			DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc);
+			printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc);
 			if (ecc & ONENAND_ECC_2BIT_ALL) {
 				mtd->ecc_stats.failed++;
 				return ecc;
 			} else if (ecc & ONENAND_ECC_1BIT_ALL)
 				mtd->ecc_stats.corrected++;
 		}
+	} else if (state == FL_READING) {
+		printk(KERN_ERR "onenand_wait: read timeout! ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt);
+		return -EIO;
 	}
 
 	return 0;
@@ -587,22 +577,32 @@
 static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
 {
 	struct onenand_chip *this = mtd->priv;
-	int block, page;
-	int i;
+	int blockpage, found = 0;
+	unsigned int i;
 
-	block = (int) (addr >> this->erase_shift);
-	page = (int) (addr >> this->page_shift);
-	page &= this->page_mask;
-
-	i = ONENAND_CURRENT_BUFFERRAM(this);
+	blockpage = (int) (addr >> this->page_shift);
 
 	/* Is there valid data? */
-	if (this->bufferram[i].block == block &&
-	    this->bufferram[i].page == page &&
-	    this->bufferram[i].valid)
-		return 1;
+	i = ONENAND_CURRENT_BUFFERRAM(this);
+	if (this->bufferram[i].blockpage == blockpage)
+		found = 1;
+	else {
+		/* Check another BufferRAM */
+		i = ONENAND_NEXT_BUFFERRAM(this);
+		if (this->bufferram[i].blockpage == blockpage) {
+			ONENAND_SET_NEXT_BUFFERRAM(this);
+			found = 1;
+		}
+	}
 
-	return 0;
+	if (found && ONENAND_IS_DDP(this)) {
+		/* Select DataRAM for DDP */
+		int block = (int) (addr >> this->erase_shift);
+		int value = onenand_bufferram_address(this, block);
+		this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
+	}
+
+	return found;
 }
 
 /**
@@ -613,31 +613,49 @@
  *
  * Update BufferRAM information
  */
-static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
+static void onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
 		int valid)
 {
 	struct onenand_chip *this = mtd->priv;
-	int block, page;
-	int i;
+	int blockpage;
+	unsigned int i;
 
-	block = (int) (addr >> this->erase_shift);
-	page = (int) (addr >> this->page_shift);
-	page &= this->page_mask;
+	blockpage = (int) (addr >> this->page_shift);
 
-	/* Invalidate BufferRAM */
-	for (i = 0; i < MAX_BUFFERRAM; i++) {
-		if (this->bufferram[i].block == block &&
-		    this->bufferram[i].page == page)
-			this->bufferram[i].valid = 0;
-	}
+	/* Invalidate another BufferRAM */
+	i = ONENAND_NEXT_BUFFERRAM(this);
+	if (this->bufferram[i].blockpage == blockpage)
+		this->bufferram[i].blockpage = -1;
 
 	/* Update BufferRAM */
 	i = ONENAND_CURRENT_BUFFERRAM(this);
-	this->bufferram[i].block = block;
-	this->bufferram[i].page = page;
-	this->bufferram[i].valid = valid;
+	if (valid)
+		this->bufferram[i].blockpage = blockpage;
+	else
+		this->bufferram[i].blockpage = -1;
+}
 
-	return 0;
+/**
+ * onenand_invalidate_bufferram - [GENERIC] Invalidate BufferRAM information
+ * @param mtd		MTD data structure
+ * @param addr		start address to invalidate
+ * @param len		length to invalidate
+ *
+ * Invalidate BufferRAM information
+ */
+static void onenand_invalidate_bufferram(struct mtd_info *mtd, loff_t addr,
+		unsigned int len)
+{
+	struct onenand_chip *this = mtd->priv;
+	int i;
+	loff_t end_addr = addr + len;
+
+	/* Invalidate BufferRAM */
+	for (i = 0; i < MAX_BUFFERRAM; i++) {
+		loff_t buf_addr = this->bufferram[i].blockpage << this->page_shift;
+		if (buf_addr >= addr && buf_addr < end_addr)
+			this->bufferram[i].blockpage = -1;
+	}
 }
 
 /**
@@ -716,7 +734,7 @@
 
 	/* Do not allow reads past end of device */
 	if ((from + len) > mtd->size) {
-		DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: Attempt read beyond end of device\n");
+		printk(KERN_ERR "onenand_read: Attempt read beyond end of device\n");
 		*retlen = 0;
 		return -EINVAL;
 	}
@@ -724,8 +742,6 @@
 	/* Grab the lock and see if the device is available */
 	onenand_get_device(mtd, FL_READING);
 
-	/* TODO handling oob */
-
 	stats = mtd->ecc_stats;
 
  	/* Read-while-load method */
@@ -754,9 +770,9 @@
  			 * Now we issued chip 1 read and pointed chip 1
  			 * bufferam so we have to point chip 0 bufferam.
  			 */
- 			if (this->device_id & ONENAND_DEVICE_IS_DDP &&
- 					unlikely(from == (this->chipsize >> 1))) {
- 				this->write_word(0, this->base + ONENAND_REG_START_ADDRESS2);
+ 			if (ONENAND_IS_DDP(this) &&
+ 			    unlikely(from == (this->chipsize >> 1))) {
+ 				this->write_word(ONENAND_DDP_CHIP0, this->base + ONENAND_REG_START_ADDRESS2);
  				boundary = 1;
  			} else
  				boundary = 0;
@@ -770,7 +786,7 @@
  			break;
  		/* Set up for next read from bufferRAM */
  		if (unlikely(boundary))
- 			this->write_word(0x8000, this->base + ONENAND_REG_START_ADDRESS2);
+ 			this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);
  		ONENAND_SET_NEXT_BUFFERRAM(this);
  		buf += thislen;
  		thislen = min_t(int, mtd->writesize, len - read);
@@ -801,20 +817,59 @@
 }
 
 /**
+ * onenand_transfer_auto_oob - [Internal] oob auto-placement transfer
+ * @param mtd		MTD device structure
+ * @param buf		destination address
+ * @param column	oob offset to read from
+ * @param thislen	oob length to read
+ */
+static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int column,
+				int thislen)
+{
+	struct onenand_chip *this = mtd->priv;
+	struct nand_oobfree *free;
+	int readcol = column;
+	int readend = column + thislen;
+	int lastgap = 0;
+	uint8_t *oob_buf = this->page_buf + mtd->writesize;
+
+	for (free = this->ecclayout->oobfree; free->length; ++free) {
+		if (readcol >= lastgap)
+			readcol += free->offset - lastgap;
+		if (readend >= lastgap)
+			readend += free->offset - lastgap;
+		lastgap = free->offset + free->length;
+	}
+	this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
+	for (free = this->ecclayout->oobfree; free->length; ++free) {
+		int free_end = free->offset + free->length;
+		if (free->offset < readend && free_end > readcol) {
+			int st = max_t(int,free->offset,readcol);
+			int ed = min_t(int,free_end,readend);
+			int n = ed - st;
+			memcpy(buf, oob_buf + st, n);
+			buf += n;
+		}
+	}
+	return 0;
+}
+
+/**
  * onenand_do_read_oob - [MTD Interface] OneNAND read out-of-band
  * @param mtd		MTD device structure
  * @param from		offset to read from
  * @param len		number of bytes to read
  * @param retlen	pointer to variable to store the number of read bytes
  * @param buf		the databuffer to put data
+ * @param mode		operation mode
  *
  * OneNAND read out-of-band data from the spare area
  */
-int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
-			size_t *retlen, u_char *buf)
+static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
+			size_t *retlen, u_char *buf, mtd_oob_mode_t mode)
 {
 	struct onenand_chip *this = mtd->priv;
-	int read = 0, thislen, column;
+	int read = 0, thislen, column, oobsize;
 	int ret = 0;
 
 	DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
@@ -822,21 +877,33 @@
 	/* Initialize return length value */
 	*retlen = 0;
 
+	if (mode == MTD_OOB_AUTO)
+		oobsize = this->ecclayout->oobavail;
+	else
+		oobsize = mtd->oobsize;
+
+	column = from & (mtd->oobsize - 1);
+
+	if (unlikely(column >= oobsize)) {
+		printk(KERN_ERR "onenand_read_oob: Attempted to start read outside oob\n");
+		return -EINVAL;
+	}
+
 	/* Do not allow reads past end of device */
-	if (unlikely((from + len) > mtd->size)) {
-		DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: Attempt read beyond end of device\n");
+	if (unlikely(from >= mtd->size ||
+		     column + len > ((mtd->size >> this->page_shift) -
+				     (from >> this->page_shift)) * oobsize)) {
+		printk(KERN_ERR "onenand_read_oob: Attempted to read beyond end of device\n");
 		return -EINVAL;
 	}
 
 	/* Grab the lock and see if the device is available */
 	onenand_get_device(mtd, FL_READING);
 
-	column = from & (mtd->oobsize - 1);
-
 	while (read < len) {
 		cond_resched();
 
-		thislen = mtd->oobsize - column;
+		thislen = oobsize - column;
 		thislen = min_t(int, thislen, len);
 
 		this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
@@ -846,11 +913,14 @@
 		ret = this->wait(mtd, FL_READING);
 		/* First copy data and check return value for ECC handling */
 
-		this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
+		if (mode == MTD_OOB_AUTO)
+			onenand_transfer_auto_oob(mtd, buf, column, thislen);
+		else
+			this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
 
 		if (ret) {
-			DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = 0x%x\n", ret);
-			goto out;
+			printk(KERN_ERR "onenand_read_oob: read failed = 0x%x\n", ret);
+			break;
 		}
 
 		read += thislen;
@@ -868,7 +938,6 @@
 		}
 	}
 
-out:
 	/* Deselect and wake up anyone waiting on the device */
 	onenand_release_device(mtd);
 
@@ -885,10 +954,132 @@
 static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
 			    struct mtd_oob_ops *ops)
 {
-	BUG_ON(ops->mode != MTD_OOB_PLACE);
-
+	switch (ops->mode) {
+	case MTD_OOB_PLACE:
+	case MTD_OOB_AUTO:
+		break;
+	case MTD_OOB_RAW:
+		/* Not implemented yet */
+	default:
+		return -EINVAL;
+	}
 	return onenand_do_read_oob(mtd, from + ops->ooboffs, ops->ooblen,
-				   &ops->oobretlen, ops->oobbuf);
+				   &ops->oobretlen, ops->oobbuf, ops->mode);
+}
+
+/**
+ * onenand_bbt_wait - [DEFAULT] wait until the command is done
+ * @param mtd		MTD device structure
+ * @param state		state to select the max. timeout value
+ *
+ * Wait for command done.
+ */
+static int onenand_bbt_wait(struct mtd_info *mtd, int state)
+{
+	struct onenand_chip *this = mtd->priv;
+	unsigned long timeout;
+	unsigned int interrupt;
+	unsigned int ctrl;
+
+	/* The 20 msec is enough */
+	timeout = jiffies + msecs_to_jiffies(20);
+	while (time_before(jiffies, timeout)) {
+		interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
+		if (interrupt & ONENAND_INT_MASTER)
+			break;
+	}
+	/* To get correct interrupt status in timeout case */
+	interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
+	ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
+
+	if (ctrl & ONENAND_CTRL_ERROR) {
+		printk(KERN_DEBUG "onenand_bbt_wait: controller error = 0x%04x\n", ctrl);
+		/* Initial bad block case */
+		if (ctrl & ONENAND_CTRL_LOAD)
+			return ONENAND_BBT_READ_ERROR;
+		return ONENAND_BBT_READ_FATAL_ERROR;
+	}
+
+	if (interrupt & ONENAND_INT_READ) {
+		int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
+		if (ecc & ONENAND_ECC_2BIT_ALL)
+			return ONENAND_BBT_READ_ERROR;
+	} else {
+		printk(KERN_ERR "onenand_bbt_wait: read timeout!"
+			"ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt);
+		return ONENAND_BBT_READ_FATAL_ERROR;
+	}
+
+	return 0;
+}
+
+/**
+ * onenand_bbt_read_oob - [MTD Interface] OneNAND read out-of-band for bbt scan
+ * @param mtd		MTD device structure
+ * @param from		offset to read from
+ * @param @ops		oob operation description structure
+ *
+ * OneNAND read out-of-band data from the spare area for bbt scan
+ */
+int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, 
+			    struct mtd_oob_ops *ops)
+{
+	struct onenand_chip *this = mtd->priv;
+	int read = 0, thislen, column;
+	int ret = 0;
+	size_t len = ops->ooblen;
+	u_char *buf = ops->oobbuf;
+
+	DEBUG(MTD_DEBUG_LEVEL3, "onenand_bbt_read_oob: from = 0x%08x, len = %zi\n", (unsigned int) from, len);
+
+	/* Initialize return value */
+	ops->oobretlen = 0;
+
+	/* Do not allow reads past end of device */
+	if (unlikely((from + len) > mtd->size)) {
+		printk(KERN_ERR "onenand_bbt_read_oob: Attempt read beyond end of device\n");
+		return ONENAND_BBT_READ_FATAL_ERROR;
+	}
+
+	/* Grab the lock and see if the device is available */
+	onenand_get_device(mtd, FL_READING);
+
+	column = from & (mtd->oobsize - 1);
+
+	while (read < len) {
+		cond_resched();
+
+		thislen = mtd->oobsize - column;
+		thislen = min_t(int, thislen, len);
+
+		this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
+
+		onenand_update_bufferram(mtd, from, 0);
+
+		ret = onenand_bbt_wait(mtd, FL_READING);
+		if (ret)
+			break;
+
+		this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
+		read += thislen;
+		if (read == len)
+			break;
+
+		buf += thislen;
+
+		/* Read more? */
+		if (read < len) {
+			/* Update Page size */
+			from += mtd->writesize;
+			column = 0;
+		}
+	}
+
+	/* Deselect and wake up anyone waiting on the device */
+	onenand_release_device(mtd);
+
+	ops->oobretlen = read;
+	return ret;
 }
 
 #ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
@@ -897,14 +1088,12 @@
  * @param mtd		MTD device structure
  * @param buf		the databuffer to verify
  * @param to		offset to read from
- * @param len		number of bytes to read and compare
  *
  */
-static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to, int len)
+static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to)
 {
 	struct onenand_chip *this = mtd->priv;
-	char *readp = this->page_buf;
-	int column = to & (mtd->oobsize - 1);
+	char *readp = this->page_buf + mtd->writesize;
 	int status, i;
 
 	this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize);
@@ -913,9 +1102,8 @@
 	if (status)
 		return status;
 
-	this->read_bufferram(mtd, ONENAND_SPARERAM, readp, column, len);
-
-	for(i = 0; i < len; i++)
+	this->read_bufferram(mtd, ONENAND_SPARERAM, readp, 0, mtd->oobsize);
+	for(i = 0; i < mtd->oobsize; i++)
 		if (buf[i] != 0xFF && buf[i] != readp[i])
 			return -EBADMSG;
 
@@ -923,41 +1111,51 @@
 }
 
 /**
- * onenand_verify_page - [GENERIC] verify the chip contents after a write
- * @param mtd		MTD device structure
- * @param buf		the databuffer to verify
+ * onenand_verify - [GENERIC] verify the chip contents after a write
+ * @param mtd          MTD device structure
+ * @param buf          the databuffer to verify
+ * @param addr         offset to read from
+ * @param len          number of bytes to read and compare
  *
- * Check DataRAM area directly
  */
-static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr)
+static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, size_t len)
 {
 	struct onenand_chip *this = mtd->priv;
-	void __iomem *dataram0, *dataram1;
+	void __iomem *dataram;
 	int ret = 0;
+	int thislen, column;
 
-	/* In partial page write, just skip it */
-	if ((addr & (mtd->writesize - 1)) != 0)
-		return 0;
+	while (len != 0) {
+		thislen = min_t(int, mtd->writesize, len);
+		column = addr & (mtd->writesize - 1);
+		if (column + thislen > mtd->writesize)
+			thislen = mtd->writesize - column;
 
-	this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
+		this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
 
-	ret = this->wait(mtd, FL_READING);
-	if (ret)
-		return ret;
+		onenand_update_bufferram(mtd, addr, 0);
 
-	onenand_update_bufferram(mtd, addr, 1);
+		ret = this->wait(mtd, FL_READING);
+		if (ret)
+			return ret;
 
-	/* Check, if the two dataram areas are same */
-	dataram0 = this->base + ONENAND_DATARAM;
-	dataram1 = dataram0 + mtd->writesize;
+		onenand_update_bufferram(mtd, addr, 1);
 
-	if (memcmp(dataram0, dataram1, mtd->writesize))
-		return -EBADMSG;
+		dataram = this->base + ONENAND_DATARAM;
+		dataram += onenand_bufferram_offset(mtd, ONENAND_DATARAM);
+
+		if (memcmp(buf, dataram + column, thislen))
+			return -EBADMSG;
+
+		len -= thislen;
+		buf += thislen;
+		addr += thislen;
+	}
 
 	return 0;
 }
 #else
-#define onenand_verify_page(...)	(0)
+#define onenand_verify(...)		(0)
 #define onenand_verify_oob(...)		(0)
 #endif
 
@@ -988,60 +1186,57 @@
 
 	/* Do not allow writes past end of device */
 	if (unlikely((to + len) > mtd->size)) {
-		DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: Attempt write to past end of device\n");
+		printk(KERN_ERR "onenand_write: Attempt write to past end of device\n");
 		return -EINVAL;
 	}
 
 	/* Reject writes, which are not page aligned */
         if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
-                DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: Attempt to write not page aligned data\n");
+                printk(KERN_ERR "onenand_write: Attempt to write not page aligned data\n");
                 return -EINVAL;
         }
 
 	column = to & (mtd->writesize - 1);
-	subpage = column || (len & (mtd->writesize - 1));
 
 	/* Grab the lock and see if the device is available */
 	onenand_get_device(mtd, FL_WRITING);
 
 	/* Loop until all data write */
 	while (written < len) {
-		int bytes = mtd->writesize;
-		int thislen = min_t(int, bytes, len - written);
+		int thislen = min_t(int, mtd->writesize - column, len - written);
 		u_char *wbuf = (u_char *) buf;
 
 		cond_resched();
 
-		this->command(mtd, ONENAND_CMD_BUFFERRAM, to, bytes);
+		this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
 
 		/* Partial page write */
+		subpage = thislen < mtd->writesize;
 		if (subpage) {
-			bytes = min_t(int, bytes - column, (int) len);
 			memset(this->page_buf, 0xff, mtd->writesize);
-			memcpy(this->page_buf + column, buf, bytes);
+			memcpy(this->page_buf + column, buf, thislen);
 			wbuf = this->page_buf;
-			/* Even though partial write, we need page size */
-			thislen = mtd->writesize;
 		}
 
-		this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, thislen);
+		this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
 		this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
 
 		this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
 
-		/* In partial page write we don't update bufferram */
-		onenand_update_bufferram(mtd, to, !subpage);
-
 		ret = this->wait(mtd, FL_WRITING);
+
+		/* In partial page write we don't update bufferram */
+		onenand_update_bufferram(mtd, to, !ret && !subpage);
+
 		if (ret) {
-			DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret);
+			printk(KERN_ERR "onenand_write: write filaed %d\n", ret);
 			break;
 		}
 
 		/* Only check verify write turn on */
-		ret = onenand_verify_page(mtd, (u_char *) wbuf, to);
+		ret = onenand_verify(mtd, (u_char *) wbuf, to, thislen);
 		if (ret) {
-			DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret);
+			printk(KERN_ERR "onenand_write: verify failed %d\n", ret);
 			break;
 		}
 
@@ -1064,20 +1259,58 @@
 }
 
 /**
+ * onenand_fill_auto_oob - [Internal] oob auto-placement transfer
+ * @param mtd		MTD device structure
+ * @param oob_buf	oob buffer
+ * @param buf		source address
+ * @param column	oob offset to write to
+ * @param thislen	oob length to write
+ */
+static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
+				  const u_char *buf, int column, int thislen)
+{
+	struct onenand_chip *this = mtd->priv;
+	struct nand_oobfree *free;
+	int writecol = column;
+	int writeend = column + thislen;
+	int lastgap = 0;
+
+	for (free = this->ecclayout->oobfree; free->length; ++free) {
+		if (writecol >= lastgap)
+			writecol += free->offset - lastgap;
+		if (writeend >= lastgap)
+			writeend += free->offset - lastgap;
+		lastgap = free->offset + free->length;
+	}
+	for (free = this->ecclayout->oobfree; free->length; ++free) {
+		int free_end = free->offset + free->length;
+		if (free->offset < writeend && free_end > writecol) {
+			int st = max_t(int,free->offset,writecol);
+			int ed = min_t(int,free_end,writeend);
+			int n = ed - st;
+			memcpy(oob_buf + st, buf, n);
+			buf += n;
+		}
+	}
+	return 0;
+}
+
+/**
  * onenand_do_write_oob - [Internal] OneNAND write out-of-band
  * @param mtd		MTD device structure
  * @param to		offset to write to
  * @param len		number of bytes to write
  * @param retlen	pointer to variable to store the number of written bytes
  * @param buf		the data to write
+ * @param mode		operation mode
  *
  * OneNAND write out-of-band
  */
 static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
-				size_t *retlen, const u_char *buf)
+				size_t *retlen, const u_char *buf, mtd_oob_mode_t mode)
 {
 	struct onenand_chip *this = mtd->priv;
-	int column, ret = 0;
+	int column, ret = 0, oobsize;
 	int written = 0;
 
 	DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
@@ -1085,9 +1318,30 @@
 	/* Initialize retlen, in case of early exit */
 	*retlen = 0;
 
-	/* Do not allow writes past end of device */
-	if (unlikely((to + len) > mtd->size)) {
-		DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: Attempt write to past end of device\n");
+	if (mode == MTD_OOB_AUTO)
+		oobsize = this->ecclayout->oobavail;
+	else
+		oobsize = mtd->oobsize;
+
+	column = to & (mtd->oobsize - 1);
+
+	if (unlikely(column >= oobsize)) {
+		printk(KERN_ERR "onenand_write_oob: Attempted to start write outside oob\n");
+		return -EINVAL;
+	}
+
+	/* For compatibility with NAND: Do not allow write past end of page */
+	if (column + len > oobsize) {
+		printk(KERN_ERR "onenand_write_oob: "
+		      "Attempt to write past end of page\n");
+		return -EINVAL;
+	}
+
+	/* Do not allow reads past end of device */
+	if (unlikely(to >= mtd->size ||
+		     column + len > ((mtd->size >> this->page_shift) -
+				     (to >> this->page_shift)) * oobsize)) {
+		printk(KERN_ERR "onenand_write_oob: Attempted to write past end of device\n");
 		return -EINVAL;
 	}
 
@@ -1096,18 +1350,19 @@
 
 	/* Loop until all data write */
 	while (written < len) {
-		int thislen = min_t(int, mtd->oobsize, len - written);
+		int thislen = min_t(int, oobsize, len - written);
 
 		cond_resched();
 
-		column = to & (mtd->oobsize - 1);
-
 		this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
 
 		/* We send data to spare ram with oobsize
 		 * to prevent byte access */
 		memset(this->page_buf, 0xff, mtd->oobsize);
-		memcpy(this->page_buf + column, buf, thislen);
+		if (mode == MTD_OOB_AUTO)
+			onenand_fill_auto_oob(mtd, this->page_buf, buf, column, thislen);
+		else
+			memcpy(this->page_buf + column, buf, thislen);
 		this->write_bufferram(mtd, ONENAND_SPARERAM, this->page_buf, 0, mtd->oobsize);
 
 		this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
@@ -1116,26 +1371,25 @@
 
 		ret = this->wait(mtd, FL_WRITING);
 		if (ret) {
-			DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: write filaed %d\n", ret);
-			goto out;
+			printk(KERN_ERR "onenand_write_oob: write failed %d\n", ret);
+			break;
 		}
 
-		ret = onenand_verify_oob(mtd, buf, to, thislen);
+		ret = onenand_verify_oob(mtd, this->page_buf, to);
 		if (ret) {
-			DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: verify failed %d\n", ret);
-			goto out;
+			printk(KERN_ERR "onenand_write_oob: verify failed %d\n", ret);
+			break;
 		}
 
 		written += thislen;
-
 		if (written == len)
 			break;
 
-		to += thislen;
+		to += mtd->writesize;
 		buf += thislen;
+		column = 0;
 	}
 
-out:
 	/* Deselect and wake up anyone waiting on the device */
 	onenand_release_device(mtd);
 
@@ -1153,10 +1407,17 @@
 static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
 			     struct mtd_oob_ops *ops)
 {
-	BUG_ON(ops->mode != MTD_OOB_PLACE);
-
+	switch (ops->mode) {
+	case MTD_OOB_PLACE:
+	case MTD_OOB_AUTO:
+		break;
+	case MTD_OOB_RAW:
+		/* Not implemented yet */
+	default:
+		return -EINVAL;
+	}
 	return onenand_do_write_oob(mtd, to + ops->ooboffs, ops->ooblen,
-				    &ops->oobretlen, ops->oobbuf);
+				    &ops->oobretlen, ops->oobbuf, ops->mode);
 }
 
 /**
@@ -1199,19 +1460,19 @@
 
 	/* Start address must align on block boundary */
 	if (unlikely(instr->addr & (block_size - 1))) {
-		DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n");
+		printk(KERN_ERR "onenand_erase: Unaligned address\n");
 		return -EINVAL;
 	}
 
 	/* Length must align on block boundary */
 	if (unlikely(instr->len & (block_size - 1))) {
-		DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Length not block aligned\n");
+		printk(KERN_ERR "onenand_erase: Length not block aligned\n");
 		return -EINVAL;
 	}
 
 	/* Do not allow erase past end of device */
 	if (unlikely((instr->len + instr->addr) > mtd->size)) {
-		DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Erase past end of device\n");
+		printk(KERN_ERR "onenand_erase: Erase past end of device\n");
 		return -EINVAL;
 	}
 
@@ -1238,10 +1499,12 @@
 
 		this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
 
+		onenand_invalidate_bufferram(mtd, addr, block_size);
+
 		ret = this->wait(mtd, FL_ERASING);
 		/* Check, if it is write protected */
 		if (ret) {
-			DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));
+			printk(KERN_ERR "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));
 			instr->state = MTD_ERASE_FAILED;
 			instr->fail_addr = addr;
 			goto erase_exit;
@@ -1322,7 +1585,7 @@
 
         /* We write two bytes, so we dont have to mess with 16 bit access */
         ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
-        return onenand_do_write_oob(mtd, ofs , 2, &retlen, buf);
+        return onenand_do_write_oob(mtd, ofs , 2, &retlen, buf, MTD_OOB_PLACE);
 }
 
 /**
@@ -1491,6 +1754,8 @@
 	struct onenand_chip *this = mtd->priv;
 
 	if (this->options & ONENAND_HAS_UNLOCK_ALL) {
+		/* Set start block address */
+		this->write_word(0, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
 		/* Write unlock command */
 		this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
 
@@ -1503,13 +1768,10 @@
 			continue;
 
 		/* Workaround for all block unlock in DDP */
-		if (this->device_id & ONENAND_DEVICE_IS_DDP) {
-			loff_t ofs;
-			size_t len;
-
+		if (ONENAND_IS_DDP(this)) {
 			/* 1st block on another chip */
-			ofs = this->chipsize >> 1;
-			len = 1 << this->erase_shift;
+			loff_t ofs = this->chipsize >> 1;
+			size_t len = mtd->erasesize;
 
 			onenand_unlock(mtd, ofs, len);
 		}
@@ -1617,7 +1879,7 @@
 	this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
 	this->wait(mtd, FL_OTPING);
 
-	ret = onenand_do_write_oob(mtd, from, len, retlen, buf);
+	ret = onenand_do_write_oob(mtd, from, len, retlen, buf, MTD_OOB_PLACE);
 
 	/* Exit OTP access mode */
 	this->command(mtd, ONENAND_CMD_RESET, 0, 0);
@@ -1823,12 +2085,13 @@
 #endif	/* CONFIG_MTD_ONENAND_OTP */
 
 /**
- * onenand_lock_scheme - Check and set OneNAND lock scheme
+ * onenand_check_features - Check and set OneNAND features
  * @param mtd		MTD data structure
  *
- * Check and set OneNAND lock scheme
+ * Check and set OneNAND features
+ * - lock scheme
  */
-static void onenand_lock_scheme(struct mtd_info *mtd)
+static void onenand_check_features(struct mtd_info *mtd)
 {
 	struct onenand_chip *this = mtd->priv;
 	unsigned int density, process;
@@ -1961,26 +2224,28 @@
 	density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
 	this->chipsize = (16 << density) << 20;
 	/* Set density mask. it is used for DDP */
-	this->density_mask = (1 << (density + 6));
+	if (ONENAND_IS_DDP(this))
+		this->density_mask = (1 << (density + 6));
+	else
+		this->density_mask = 0;
 
 	/* OneNAND page size & block size */
 	/* The data buffer size is equal to page size */
 	mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
 	mtd->oobsize = mtd->writesize >> 5;
-	/* Pagers per block is always 64 in OneNAND */
+	/* Pages per a block are always 64 in OneNAND */
 	mtd->erasesize = mtd->writesize << 6;
 
 	this->erase_shift = ffs(mtd->erasesize) - 1;
 	this->page_shift = ffs(mtd->writesize) - 1;
-	this->ppb_shift = (this->erase_shift - this->page_shift);
-	this->page_mask = (mtd->erasesize / mtd->writesize) - 1;
+	this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1;
 
 	/* REVIST: Multichip handling */
 
 	mtd->size = this->chipsize;
 
-	/* Check OneNAND lock scheme */
-	onenand_lock_scheme(mtd);
+	/* Check OneNAND features */
+	onenand_check_features(mtd);
 
 	return 0;
 }
@@ -2021,6 +2286,7 @@
  */
 int onenand_scan(struct mtd_info *mtd, int maxchips)
 {
+	int i;
 	struct onenand_chip *this = mtd->priv;
 
 	if (!this->read_word)
@@ -2092,12 +2358,21 @@
 	}
 
 	this->subpagesize = mtd->writesize >> mtd->subpage_sft;
+
+	/*
+	 * The number of bytes available for a client to place data into
+	 * the out of band area
+	 */
+	this->ecclayout->oobavail = 0;
+	for (i = 0; this->ecclayout->oobfree[i].length; i++)
+		this->ecclayout->oobavail +=
+			this->ecclayout->oobfree[i].length;
+
 	mtd->ecclayout = this->ecclayout;
 
 	/* Fill in remaining MTD driver data */
 	mtd->type = MTD_NANDFLASH;
 	mtd->flags = MTD_CAP_NANDFLASH;
-	mtd->ecctype = MTD_ECC_SW;
 	mtd->erase = onenand_erase;
 	mtd->point = NULL;
 	mtd->unpoint = NULL;
@@ -2144,8 +2419,11 @@
 	del_mtd_device (mtd);
 
 	/* Free bad block table memory, if allocated */
-	if (this->bbm)
+	if (this->bbm) {
+		struct bbm_info *bbm = this->bbm;
+		kfree(bbm->bbt);
 		kfree(this->bbm);
+	}
 	/* Buffer allocated by onenand_scan */
 	if (this->options & ONENAND_PAGEBUF_ALLOC)
 		kfree(this->page_buf);
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
index 98f8fd1..aecdd50 100644
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -17,8 +17,8 @@
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/compatmac.h>
 
-extern int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
-			       size_t *retlen, u_char *buf);
+extern int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
+				struct mtd_oob_ops *ops);
 
 /**
  * check_short_pattern - [GENERIC] check if a pattern is in the buffer
@@ -65,10 +65,11 @@
 	int startblock;
 	loff_t from;
 	size_t readlen, ooblen;
+	struct mtd_oob_ops ops;
 
 	printk(KERN_INFO "Scanning device for bad blocks\n");
 
-	len = 1;
+	len = 2;
 
 	/* We need only read few bytes from the OOB area */
 	scanlen = ooblen = 0;
@@ -82,22 +83,24 @@
 	startblock = 0;
 	from = 0;
 
+	ops.mode = MTD_OOB_PLACE;
+	ops.ooblen = readlen;
+	ops.oobbuf = buf;
+	ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
+
 	for (i = startblock; i < numblocks; ) {
 		int ret;
 
 		for (j = 0; j < len; j++) {
-			size_t retlen;
-
 			/* No need to read pages fully,
 			 * just read required OOB bytes */
-			ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs,
-						  readlen, &retlen, &buf[0]);
+			ret = onenand_bbt_read_oob(mtd, from + j * mtd->writesize + bd->offs, &ops);
 
 			/* If it is a initial bad block, just ignore it */
-			if (ret && !(ret & ONENAND_CTRL_LOAD))
-				return ret;
+			if (ret == ONENAND_BBT_READ_FATAL_ERROR)
+				return -EIO;
 
-			if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
+			if (ret || check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
 				bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
 				printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
 					i >> 1, (unsigned int) from);
@@ -168,8 +171,8 @@
  * marked good / bad blocks and writes the bad block table(s) to
  * the selected place.
  *
- * The bad block table memory is allocated here. It must be freed
- * by calling the onenand_free_bbt function.
+ * The bad block table memory is allocated here. It is freed
+ * by the onenand_release function.
  *
  */
 int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c
index 035cd9b..a61351f 100644
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -94,8 +94,19 @@
 			 * (NOTE: this is 'size' not 'data_length'; size is
 			 * the full size of the entry.)
 			 */
-			if (swab32(buf[i].size) == master->erasesize) {
+
+			/* RedBoot can combine the FIS directory and
+			   config partitions into a single eraseblock;
+			   we assume wrong-endian if either the swapped
+			   'size' matches the eraseblock size precisely,
+			   or if the swapped size actually fits in an
+			   eraseblock while the unswapped size doesn't. */
+			if (swab32(buf[i].size) == master->erasesize ||
+			    (buf[i].size > master->erasesize
+			     && swab32(buf[i].size) < master->erasesize)) {
 				int j;
+				/* Update numslots based on actual FIS directory size */
+				numslots = swab32(buf[i].size) / sizeof (struct fis_image_desc);
 				for (j = 0; j < numslots; ++j) {
 
 					/* A single 0xff denotes a deleted entry.
@@ -120,11 +131,11 @@
 					swab32s(&buf[j].desc_cksum);
 					swab32s(&buf[j].file_cksum);
 				}
+			} else if (buf[i].size < master->erasesize) {
+				/* Update numslots based on actual FIS directory size */
+				numslots = buf[i].size / sizeof(struct fis_image_desc);
 			}
 			break;
-		} else {
-			/* re-calculate of real numslots */
-			numslots = buf[i].size / sizeof(struct fis_image_desc);
 		}
 	}
 	if (i == numslots) {
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 35ad5cf..99304b2 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -1109,6 +1109,8 @@
 
 	assert (dev != NULL);
 
+	flush_scheduled_work();
+
 	unregister_netdev (dev);
 
 	__rtl8139_cleanup_dev (dev);
@@ -1603,18 +1605,21 @@
 	struct net_device *dev = tp->mii.dev;
 	unsigned long thr_delay = next_tick;
 
+	rtnl_lock();
+
+	if (!netif_running(dev))
+		goto out_unlock;
+
 	if (tp->watchdog_fired) {
 		tp->watchdog_fired = 0;
 		rtl8139_tx_timeout_task(work);
-	} else if (rtnl_trylock()) {
-		rtl8139_thread_iter (dev, tp, tp->mmio_addr);
-		rtnl_unlock ();
-	} else {
-		/* unlikely race.  mitigate with fast poll. */
-		thr_delay = HZ / 2;
-	}
+	} else
+		rtl8139_thread_iter(dev, tp, tp->mmio_addr);
 
-	schedule_delayed_work(&tp->thread, thr_delay);
+	if (tp->have_thread)
+		schedule_delayed_work(&tp->thread, thr_delay);
+out_unlock:
+	rtnl_unlock ();
 }
 
 static void rtl8139_start_thread(struct rtl8139_private *tp)
@@ -1626,19 +1631,11 @@
 		return;
 
 	tp->have_thread = 1;
+	tp->watchdog_fired = 0;
 
 	schedule_delayed_work(&tp->thread, next_tick);
 }
 
-static void rtl8139_stop_thread(struct rtl8139_private *tp)
-{
-	if (tp->have_thread) {
-		cancel_rearming_delayed_work(&tp->thread);
-		tp->have_thread = 0;
-	} else
-		flush_scheduled_work();
-}
-
 static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
 {
 	tp->cur_tx = 0;
@@ -1696,12 +1693,11 @@
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
 
+	tp->watchdog_fired = 1;
 	if (!tp->have_thread) {
-		INIT_DELAYED_WORK(&tp->thread, rtl8139_tx_timeout_task);
+		INIT_DELAYED_WORK(&tp->thread, rtl8139_thread);
 		schedule_delayed_work(&tp->thread, next_tick);
-	} else
-		tp->watchdog_fired = 1;
-
+	}
 }
 
 static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
@@ -2233,8 +2229,6 @@
 
 	netif_stop_queue (dev);
 
-	rtl8139_stop_thread(tp);
-
 	if (netif_msg_ifdown(tp))
 		printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
 			dev->name, RTL_R16 (IntrStatus));
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index bd76b12..d9400ef 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2125,14 +2125,16 @@
 	  will be called sky2.  This is recommended.
 
 config SK98LIN
-	tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
+	tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support (DEPRECATED)"
 	depends on PCI
 	---help---
 	  Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx
 	  compliant Gigabit Ethernet Adapter.
 
-	  This driver supports the original Yukon chipset. A cleaner driver is 
-	  also available (skge) which seems to work better than this one.
+	  This driver supports the original Yukon chipset. This driver is
+	  deprecated and will be removed from the kernel in the near future,
+	  it has been replaced by the skge driver. skge is cleaner and
+	  seems to work better.
 
 	  This driver does not support the newer Yukon2 chipset. A separate
 	  driver, sky2, is provided to support Yukon2-based adapters.
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index d671058..bd000b8 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -3253,7 +3253,7 @@
 #define IFE_PMC_AUTO_MDIX                    0x0080  /* 1=enable MDI/MDI-X feature, default 0=disabled */
 #define IFE_PMC_FORCE_MDIX                   0x0040  /* 1=force MDIX-X, 0=force MDI */
 #define IFE_PMC_MDIX_STATUS                  0x0020  /* 1=MDI-X, 0=MDI */
-#define IFE_PMC_AUTO_MDIX_COMPLETE           0x0010  /* Resolution algorthm is completed */
+#define IFE_PMC_AUTO_MDIX_COMPLETE           0x0010  /* Resolution algorithm is completed */
 #define IFE_PMC_MDIX_MODE_SHIFT              6
 #define IFE_PHC_MDIX_RESET_ALL_MASK          0x0000  /* Disable auto MDI-X */
 
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
index 4a50fcb..3868b80 100644
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -714,13 +714,6 @@
  * check to make sure we've not become wedged.
  */
 
-/*
- * Handle an EtherExpress interrupt
- * If we've finished initializing, start the RU and CU up.
- * If we've already started, reap tx buffers, handle any received packets,
- * check to make sure we've not become wedged.
- */
-
 static unsigned short eexp_start_irq(struct net_device *dev,
 				     unsigned short status)
 {
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
index feb0ada..6e90619 100644
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -138,7 +138,7 @@
 	---help---
 	  This is one of two drivers for Baycom style simple amateur radio
 	  modems that connect to a serial interface. The driver supports the
-	  ser12 design in full-duplex mode. This is the old driver.  It is
+	  ser12 design in half-duplex mode. This is the old driver.  It is
 	  still provided in case your serial interface chip does not work with
 	  the full-duplex driver. This driver is depreciated.  To configure
 	  the driver, use the sethdlc utility available in the standard ax25
@@ -190,3 +190,4 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called yam.
 
+ 
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 153b6dc..84aa211 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -52,6 +52,7 @@
 #include <linux/hdlcdrv.h>
 #include <linux/baycom.h>
 #include <linux/jiffies.h>
+#include <linux/random.h>
 #include <net/ax25.h> 
 #include <asm/uaccess.h>
 
@@ -433,16 +434,6 @@
 
 /* ---------------------------------------------------------------------- */
 
-static unsigned short random_seed;
-
-static inline unsigned short random_num(void)
-{
-	random_seed = 28629 * random_seed + 157;
-	return random_seed;
-}
-
-/* ---------------------------------------------------------------------- */
-
 static int transmit(struct baycom_state *bc, int cnt, unsigned char stat)
 {
 	struct parport *pp = bc->pdev->port;
@@ -464,7 +455,7 @@
 			if ((--bc->hdlctx.slotcnt) > 0)
 				return 0;
 			bc->hdlctx.slotcnt = bc->ch_params.slottime;
-			if ((random_num() % 256) > bc->ch_params.ppersist)
+			if ((random32() % 256) > bc->ch_params.ppersist)
 				return 0;
 		}
 	}
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index 452873e..f5a17ad 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -56,6 +56,7 @@
 #include <linux/if_arp.h>
 #include <linux/skbuff.h>
 #include <linux/hdlcdrv.h>
+#include <linux/random.h>
 #include <net/ax25.h> 
 #include <asm/uaccess.h>
 
@@ -371,16 +372,6 @@
 
 /* ---------------------------------------------------------------------- */
 
-static unsigned short random_seed;
-
-static inline unsigned short random_num(void)
-{
-	random_seed = 28629 * random_seed + 157;
-	return random_seed;
-}
-
-/* ---------------------------------------------------------------------- */
-
 void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s)
 {
 	if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt || !s->skb) 
@@ -396,7 +387,7 @@
 	if ((--s->hdlctx.slotcnt) > 0)
 		return;
 	s->hdlctx.slotcnt = s->ch_params.slottime;
-	if ((random_num() % 256) > s->ch_params.ppersist)
+	if ((random32() % 256) > s->ch_params.ppersist)
 		return;
 	start_tx(dev, s);
 }
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 08f2711..ee3ea4f 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -50,6 +50,7 @@
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/bitops.h>
+#include <linux/random.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <linux/interrupt.h>
@@ -566,14 +567,6 @@
 	ptt_on(dev);
 }
 
-static unsigned short random_seed;
-
-static inline unsigned short random_num(void)
-{
-	random_seed = 28629 * random_seed + 157;
-	return random_seed;
-}
-
 static void yam_arbitrate(struct net_device *dev)
 {
 	struct yam_port *yp = netdev_priv(dev);
@@ -600,7 +593,7 @@
 	yp->slotcnt = yp->slot / 10;
 
 	/* is random > persist ? */
-	if ((random_num() % 256) > yp->pers)
+	if ((random32() % 256) > yp->pers)
 		return;
 
 	yam_start_tx(dev, yp);
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index ffa0afd..adf29dd 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -244,6 +244,9 @@
 	MII_EN_SCRM	= 0x0004,	/* enable scrambler (tp) */
 };
 
+enum {
+	NATSEMI_FLAG_IGNORE_PHY		= 0x1,
+};
 
 /* array of board data directly indexed by pci_tbl[x].driver_data */
 static const struct {
@@ -251,10 +254,12 @@
 	unsigned long flags;
 	unsigned int eeprom_size;
 } natsemi_pci_info[] __devinitdata = {
+	{ "Aculab E1/T1 PMXc cPCI carrier card", NATSEMI_FLAG_IGNORE_PHY, 128 },
 	{ "NatSemi DP8381[56]", 0, 24 },
 };
 
 static const struct pci_device_id natsemi_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_NS, 0x0020, 0x12d9,     0x000c,     0, 0, 0 },
 	{ PCI_VENDOR_ID_NS, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ }	/* terminate list */
 };
@@ -568,6 +573,8 @@
 	u32 intr_status;
 	/* Do not touch the nic registers */
 	int hands_off;
+	/* Don't pay attention to the reported link state. */
+	int ignore_phy;
 	/* external phy that is used: only valid if dev->if_port != PORT_TP */
 	int mii;
 	int phy_addr_external;
@@ -696,7 +703,10 @@
 	struct netdev_private *np = netdev_priv(dev);
 	u32 tmp;
 
-	netif_carrier_off(dev);
+	if (np->ignore_phy)
+		netif_carrier_on(dev);
+	else
+		netif_carrier_off(dev);
 
 	/* get the initial settings from hardware */
 	tmp            = mdio_read(dev, MII_BMCR);
@@ -806,8 +816,13 @@
 	np->hands_off = 0;
 	np->intr_status = 0;
 	np->eeprom_size = natsemi_pci_info[chip_idx].eeprom_size;
+	if (natsemi_pci_info[chip_idx].flags & NATSEMI_FLAG_IGNORE_PHY)
+		np->ignore_phy = 1;
+	else
+		np->ignore_phy = 0;
 
 	/* Initial port:
+	 * - If configured to ignore the PHY set up for external.
 	 * - If the nic was configured to use an external phy and if find_mii
 	 *   finds a phy: use external port, first phy that replies.
 	 * - Otherwise: internal port.
@@ -815,7 +830,7 @@
 	 * The address would be used to access a phy over the mii bus, but
 	 * the internal phy is accessed through mapped registers.
 	 */
-	if (readl(ioaddr + ChipConfig) & CfgExtPhy)
+	if (np->ignore_phy || readl(ioaddr + ChipConfig) & CfgExtPhy)
 		dev->if_port = PORT_MII;
 	else
 		dev->if_port = PORT_TP;
@@ -825,7 +840,9 @@
 
 	if (dev->if_port != PORT_TP) {
 		np->phy_addr_external = find_mii(dev);
-		if (np->phy_addr_external == PHY_ADDR_NONE) {
+		/* If we're ignoring the PHY it doesn't matter if we can't
+		 * find one. */
+		if (!np->ignore_phy && np->phy_addr_external == PHY_ADDR_NONE) {
 			dev->if_port = PORT_TP;
 			np->phy_addr_external = PHY_ADDR_INTERNAL;
 		}
@@ -891,6 +908,8 @@
 		printk("%02x, IRQ %d", dev->dev_addr[i], irq);
 		if (dev->if_port == PORT_TP)
 			printk(", port TP.\n");
+		else if (np->ignore_phy)
+			printk(", port MII, ignoring PHY\n");
 		else
 			printk(", port MII, phy ad %d.\n", np->phy_addr_external);
 	}
@@ -1571,9 +1590,13 @@
 {
 	struct netdev_private *np = netdev_priv(dev);
 	void __iomem * ioaddr = ns_ioaddr(dev);
-	int duplex;
+	int duplex = np->duplex;
 	u16 bmsr;
 
+	/* If we are ignoring the PHY then don't try reading it. */
+	if (np->ignore_phy)
+		goto propagate_state;
+
 	/* The link status field is latched: it remains low after a temporary
 	 * link failure until it's read. We need the current link status,
 	 * thus read twice.
@@ -1585,7 +1608,7 @@
 		if (netif_carrier_ok(dev)) {
 			if (netif_msg_link(np))
 				printk(KERN_NOTICE "%s: link down.\n",
-					dev->name);
+				       dev->name);
 			netif_carrier_off(dev);
 			undo_cable_magic(dev);
 		}
@@ -1609,6 +1632,7 @@
 			duplex = 1;
 	}
 
+propagate_state:
 	/* if duplex is set then bit 28 must be set, too */
 	if (duplex ^ !!(np->rx_config & RxAcceptTx)) {
 		if (netif_msg_link(np))
@@ -2819,6 +2843,15 @@
 	}
 
 	/*
+	 * If we're ignoring the PHY then autoneg and the internal
+	 * transciever are really not going to work so don't let the
+	 * user select them.
+	 */
+	if (np->ignore_phy && (ecmd->autoneg == AUTONEG_ENABLE ||
+			       ecmd->port == PORT_TP))
+		return -EINVAL;
+
+	/*
 	 * maxtxpkt, maxrxpkt: ignored for now.
 	 *
 	 * transceiver:
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 5598d86..13cf06e 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1733,6 +1733,8 @@
 	assert(dev != NULL);
 	assert(tp != NULL);
 
+	flush_scheduled_work();
+
 	unregister_netdev(dev);
 	rtl8169_release_board(pdev, dev, tp->mmio_addr);
 	pci_set_drvdata(pdev, NULL);
@@ -2161,10 +2163,13 @@
 	struct net_device *dev = tp->dev;
 	int ret;
 
-	if (netif_running(dev)) {
-		rtl8169_wait_for_quiescence(dev);
-		rtl8169_close(dev);
-	}
+	rtnl_lock();
+
+	if (!netif_running(dev))
+		goto out_unlock;
+
+	rtl8169_wait_for_quiescence(dev);
+	rtl8169_close(dev);
 
 	ret = rtl8169_open(dev);
 	if (unlikely(ret < 0)) {
@@ -2179,6 +2184,9 @@
 		}
 		rtl8169_schedule_work(dev, rtl8169_reinit_task);
 	}
+
+out_unlock:
+	rtnl_unlock();
 }
 
 static void rtl8169_reset_task(struct work_struct *work)
@@ -2187,8 +2195,10 @@
 		container_of(work, struct rtl8169_private, task.work);
 	struct net_device *dev = tp->dev;
 
+	rtnl_lock();
+
 	if (!netif_running(dev))
-		return;
+		goto out_unlock;
 
 	rtl8169_wait_for_quiescence(dev);
 
@@ -2210,6 +2220,9 @@
 		}
 		rtl8169_schedule_work(dev, rtl8169_reset_task);
 	}
+
+out_unlock:
+	rtnl_unlock();
 }
 
 static void rtl8169_tx_timeout(struct net_device *dev)
@@ -2722,8 +2735,6 @@
 
 	netif_stop_queue(dev);
 
-	flush_scheduled_work();
-
 core_down:
 	spin_lock_irq(&tp->lock);
 
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index e8e0d94..fd85648 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -3758,7 +3758,6 @@
 {
 	struct s2io_nic *sp = dev->priv;
 
-	flush_scheduled_work();
 	netif_stop_queue(dev);
 	/* Reset card, kill tasklet and free Tx and Rx buffers. */
 	s2io_card_down(sp);
@@ -5847,9 +5846,14 @@
 	register u64 val64;
 	u16 subid;
 
+	rtnl_lock();
+
+	if (!netif_running(dev))
+		goto out_unlock;
+
 	if (test_and_set_bit(0, &(nic->link_state))) {
 		/* The card is being reset, no point doing anything */
-		return;
+		goto out_unlock;
 	}
 
 	subid = nic->pdev->subsystem_device;
@@ -5903,6 +5907,9 @@
 		s2io_link(nic, LINK_DOWN);
 	}
 	clear_bit(0, &(nic->link_state));
+
+out_unlock:
+	rtnl_lock();
 }
 
 static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
@@ -6356,6 +6363,11 @@
 	struct s2io_nic *sp = container_of(work, struct s2io_nic, rst_timer_task);
 	struct net_device *dev = sp->dev;
 
+	rtnl_lock();
+
+	if (!netif_running(dev))
+		goto out_unlock;
+
 	s2io_card_down(sp);
 	if (s2io_card_up(sp)) {
 		DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
@@ -6364,7 +6376,8 @@
 	netif_wake_queue(dev);
 	DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n",
 		  dev->name);
-
+out_unlock:
+	rtnl_unlock();
 }
 
 /**
@@ -7173,6 +7186,8 @@
 		return;
 	}
 
+	flush_scheduled_work();
+
 	sp = dev->priv;
 	unregister_netdev(dev);
 
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 45d91b1..b08508b 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -909,6 +909,9 @@
 
 	rtnl_lock();
 
+	if (!netif_running(dev))
+		goto out_unlock;
+
 	val = mdio_read(ioaddr, phy_id, MII_BMCR);
 	if (val & BMCR_RESET) {
 		// FIXME: needlessly high ?  -- FR 02/07/2005
@@ -981,6 +984,7 @@
 		netif_carrier_on(dev);
 	}
 
+out_unlock:
 	rtnl_unlock();
 }
 
@@ -1102,8 +1106,6 @@
 
 	netif_stop_queue(dev);
 
-	flush_scheduled_work();
-
 	do {
 		spin_lock_irq(&tp->lock);
 
@@ -1857,6 +1859,7 @@
 	struct net_device *dev = pci_get_drvdata(pdev);
 
 	sis190_mii_remove(dev);
+	flush_scheduled_work();
 	unregister_netdev(dev);
 	sis190_release_board(pdev);
 	pci_set_drvdata(pdev, NULL);
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index e482e7f..c3d2e0a 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -1419,7 +1419,8 @@
 	mutex_unlock(&hw->phy_mutex);
 
 nochange:
-	schedule_delayed_work(&skge->link_thread, LINK_HZ);
+	if (netif_running(dev))
+		schedule_delayed_work(&skge->link_thread, LINK_HZ);
 }
 
 static void genesis_mac_init(struct skge_hw *hw, int port)
@@ -2530,7 +2531,7 @@
 
 	netif_stop_queue(dev);
 	if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)
-		cancel_rearming_delayed_work(&skge->link_thread);
+		cancel_delayed_work(&skge->link_thread);
 
 	skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
 	if (hw->chip_id == CHIP_ID_GENESIS)
@@ -3690,6 +3691,8 @@
 	if (!hw)
 		return;
 
+	flush_scheduled_work();
+
 	if ((dev1 = hw->dev[1]))
 		unregister_netdev(dev1);
 	dev0 = hw->dev[0];
@@ -3704,8 +3707,6 @@
 	skge_write16(hw, B0_LED, LED_STAT_OFF);
 	skge_write8(hw, B0_CTST, CS_RST_SET);
 
-	flush_scheduled_work();
-
 	free_irq(pdev->irq, hw);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 5eb8163..b042397 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -1168,7 +1168,7 @@
 	 m.mmr_unused0[6],
 	 m.mmr_unused0[7]);
 #endif	/* DEBUG_SHOW_UNUSED */
-  printk(KERN_DEBUG "Encryption algorythm: %02X - Status: %02X\n",
+  printk(KERN_DEBUG "Encryption algorithm: %02X - Status: %02X\n",
 	 m.mmr_des_avail, m.mmr_des_status);
 #ifdef DEBUG_SHOW_UNUSED
   printk(KERN_DEBUG "mmc_unused1[]: %02X:%02X:%02X:%02X:%02X\n",
@@ -3590,9 +3590,9 @@
   cfblk.acloc = TRUE;           /* Disable source addr insertion by i82593 */
   cfblk.preamb_len = 0;         /* 2 bytes preamble (SFD) */
   cfblk.loopback = FALSE;
-  cfblk.lin_prio = 0;   	/* conform to 802.3 backoff algoritm */
-  cfblk.exp_prio = 5;	        /* conform to 802.3 backoff algoritm */
-  cfblk.bof_met = 1;	        /* conform to 802.3 backoff algoritm */
+  cfblk.lin_prio = 0;   	/* conform to 802.3 backoff algorithm */
+  cfblk.exp_prio = 5;	        /* conform to 802.3 backoff algorithm */
+  cfblk.bof_met = 1;	        /* conform to 802.3 backoff algorithm */
   cfblk.ifrm_spc = 0x20 >> 4;	/* 32 bit times interframe spacing */
   cfblk.slottim_low = 0x20 >> 5;	/* 32 bit times slot time */
   cfblk.slottim_hi = 0x0;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 4438ae1..a3c1755 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -415,6 +415,7 @@
  * __pci_register_driver - register a new pci driver
  * @drv: the driver structure to register
  * @owner: owner module of drv
+ * @mod_name: module name string
  * 
  * Adds the driver structure to the list of registered drivers.
  * Returns a negative value on error, otherwise 0. 
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 7a94076..cd913a2 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -143,6 +143,14 @@
 	return sprintf (buf, "%u\n", atomic_read(&pdev->enable_cnt));
 }
 
+#ifdef CONFIG_NUMA
+static ssize_t
+numa_node_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sprintf (buf, "%d\n", dev->numa_node);
+}
+#endif
+
 static ssize_t
 msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -194,6 +202,9 @@
 	__ATTR_RO(irq),
 	__ATTR_RO(local_cpus),
 	__ATTR_RO(modalias),
+#ifdef CONFIG_NUMA
+	__ATTR_RO(numa_node),
+#endif
 	__ATTR(enable, 0600, is_enabled_show, is_enabled_store),
 	__ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
 		broken_parity_status_show,broken_parity_status_store),
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 8b44cff..1e74e1e 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -21,6 +21,12 @@
 
 unsigned int pci_pm_d3_delay = 10;
 
+#define DEFAULT_CARDBUS_IO_SIZE		(256)
+#define DEFAULT_CARDBUS_MEM_SIZE	(64*1024*1024)
+/* pci=cbmemsize=nnM,cbiosize=nn can override this */
+unsigned long pci_cardbus_io_size = DEFAULT_CARDBUS_IO_SIZE;
+unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE;
+
 /**
  * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
  * @bus: pointer to PCI bus structure to search
@@ -1300,7 +1306,7 @@
 
 /**
  * pci_select_bars - Make BAR mask from the type of resource
- * @pdev: the PCI device for which BAR mask is made
+ * @dev: the PCI device for which BAR mask is made
  * @flags: resource type mask to be selected
  *
  * This helper routine makes bar mask from the type of resource.
@@ -1333,6 +1339,10 @@
 		if (*str && (str = pcibios_setup(str)) && *str) {
 			if (!strcmp(str, "nomsi")) {
 				pci_no_msi();
+			} else if (!strncmp(str, "cbiosize=", 9)) {
+				pci_cardbus_io_size = memparse(str + 9, &str);
+			} else if (!strncmp(str, "cbmemsize=", 10)) {
+				pci_cardbus_mem_size = memparse(str + 10, &str);
 			} else {
 				printk(KERN_ERR "PCI: Unknown option `%s'\n",
 						str);
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index 3c0a58f..bf655db 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -85,7 +85,7 @@
 	struct mutex rpc_mutex;		/*
 					 * only one thread could do
 					 * recovery on the same
-					 * root port hierachy
+					 * root port hierarchy
 					 */
 	wait_queue_head_t wait_release;
 };
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 89f3036..3554f39 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -36,13 +36,6 @@
 
 #define ROUND_UP(x, a)		(((x) + (a) - 1) & ~((a) - 1))
 
-/*
- * FIXME: IO should be max 256 bytes.  However, since we may
- * have a P2P bridge below a cardbus bridge, we need 4K.
- */
-#define CARDBUS_IO_SIZE		(256)
-#define CARDBUS_MEM_SIZE	(64*1024*1024)
-
 static void __devinit
 pbus_assign_resources_sorted(struct pci_bus *bus)
 {
@@ -415,12 +408,12 @@
 	 * Reserve some resources for CardBus.  We reserve
 	 * a fixed amount of bus space for CardBus bridges.
 	 */
-	b_res[0].start = CARDBUS_IO_SIZE;
-	b_res[0].end = b_res[0].start + CARDBUS_IO_SIZE - 1;
+	b_res[0].start = pci_cardbus_io_size;
+	b_res[0].end = b_res[0].start + pci_cardbus_io_size - 1;
 	b_res[0].flags |= IORESOURCE_IO;
 
-	b_res[1].start = CARDBUS_IO_SIZE;
-	b_res[1].end = b_res[1].start + CARDBUS_IO_SIZE - 1;
+	b_res[1].start = pci_cardbus_io_size;
+	b_res[1].end = b_res[1].start + pci_cardbus_io_size - 1;
 	b_res[1].flags |= IORESOURCE_IO;
 
 	/*
@@ -440,16 +433,16 @@
 	 * twice the size.
 	 */
 	if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) {
-		b_res[2].start = CARDBUS_MEM_SIZE;
-		b_res[2].end = b_res[2].start + CARDBUS_MEM_SIZE - 1;
+		b_res[2].start = pci_cardbus_mem_size;
+		b_res[2].end = b_res[2].start + pci_cardbus_mem_size - 1;
 		b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
 
-		b_res[3].start = CARDBUS_MEM_SIZE;
-		b_res[3].end = b_res[3].start + CARDBUS_MEM_SIZE - 1;
+		b_res[3].start = pci_cardbus_mem_size;
+		b_res[3].end = b_res[3].start + pci_cardbus_mem_size - 1;
 		b_res[3].flags |= IORESOURCE_MEM;
 	} else {
-		b_res[3].start = CARDBUS_MEM_SIZE * 2;
-		b_res[3].end = b_res[3].start + CARDBUS_MEM_SIZE * 2 - 1;
+		b_res[3].start = pci_cardbus_mem_size * 2;
+		b_res[3].end = b_res[3].start + pci_cardbus_mem_size * 2 - 1;
 		b_res[3].flags |= IORESOURCE_MEM;
 	}
 }
diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
index a251289..568f187 100644
--- a/drivers/pci/setup-irq.c
+++ b/drivers/pci/setup-irq.c
@@ -24,7 +24,7 @@
 	       int (*map_irq)(struct pci_dev *, u8, u8))
 {
 	u8 pin, slot;
-	int irq;
+	int irq = 0;
 
 	/* If this device is not on the primary bus, we need to figure out
 	   which interrupt pin it will come in on.   We know which slot it
@@ -33,16 +33,18 @@
 	   apply the swizzle function.  */
 
 	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-	/* Cope with 0 and illegal. */
-	if (pin == 0 || pin > 4)
+	/* Cope with illegal. */
+	if (pin > 4)
 		pin = 1;
 
-	/* Follow the chain of bridges, swizzling as we go.  */
-	slot = (*swizzle)(dev, &pin);
+	if (pin != 0) {
+		/* Follow the chain of bridges, swizzling as we go.  */
+		slot = (*swizzle)(dev, &pin);
 
-	irq = (*map_irq)(dev, slot, pin);
-	if (irq == -1)
-		irq = 0;
+		irq = (*map_irq)(dev, slot, pin);
+		if (irq == -1)
+			irq = 0;
+	}
 	dev->irq = irq;
 
 	pr_debug("PCI: fixup irq: (%s) got %d\n",
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index b318628..99baabc 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -277,7 +277,7 @@
 		board->det_pin, board->irq_pin);
 
 	cf->socket.owner = THIS_MODULE;
-	cf->socket.dev.dev = &pdev->dev;
+	cf->socket.dev.parent = &pdev->dev;
 	cf->socket.ops = &at91_cf_ops;
 	cf->socket.resource_ops = &pccard_static_ops;
 	cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 2d7effe..a1bd763 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -40,8 +40,6 @@
 
 /*====================================================================*/
 
-#define FIND_FIRST_BIT(n)	((n) - ((n) & ((n)-1)))
-
 /* Offsets in the Expansion ROM Image Header */
 #define ROM_SIGNATURE		0x0000	/* 2 bytes */
 #define ROM_DATA_PTR		0x0018	/* 2 bytes */
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index d2a3bea..aa7779d 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -478,7 +478,7 @@
  *
  * Returns: the number of characters added to the buffer
  */
-static ssize_t show_status(struct device *dev, char *buf)
+static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct soc_pcmcia_socket *skt =
 		container_of(dev, struct soc_pcmcia_socket, socket.dev);
@@ -501,7 +501,7 @@
 
 	return p-buf;
 }
-static CLASS_DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
+static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
 
 
 static struct pccard_operations soc_common_pcmcia_operations = {
@@ -660,7 +660,7 @@
 
 		skt->socket.ops = &soc_common_pcmcia_operations;
 		skt->socket.owner = ops->owner;
-		skt->socket.dev.dev = dev;
+		skt->socket.dev.parent = dev;
 
 		init_timer(&skt->poll_timer);
 		skt->poll_timer.function = soc_common_pcmcia_poll_event;
@@ -747,7 +747,7 @@
 
 		add_timer(&skt->poll_timer);
 
-		device_create_file(&skt->socket.dev, &device_attr_status);
+		device_create_file(&skt->socket.dev, &dev_attr_status);
 	}
 
 	dev_set_drvdata(dev, sinfo);
diff --git a/drivers/pnp/pnpacpi/Kconfig b/drivers/pnp/pnpacpi/Kconfig
index ad27e5e..b04767c 100644
--- a/drivers/pnp/pnpacpi/Kconfig
+++ b/drivers/pnp/pnpacpi/Kconfig
@@ -2,17 +2,5 @@
 # Plug and Play ACPI configuration
 #
 config PNPACPI
-	bool "Plug and Play ACPI support"
-	depends on PNP && ACPI
-	default y
-	---help---
-	  Linux uses the PNPACPI to autodetect built-in
-	  mainboard resources (e.g. parallel port resources).
-
-          Some features (e.g. real hotplug) are not currently
-          implemented.
-
-          If you would like the kernel to detect and allocate resources to
-          your mainboard devices (on some systems they are disabled by the
-          BIOS) say Y here.  Also the PNPACPI can help prevent resource
-          conflicts between mainboard devices and other bus devices.
+	bool
+	default (PNP && ACPI)
diff --git a/drivers/ps3/Makefile b/drivers/ps3/Makefile
index 96958c0..e251d1c 100644
--- a/drivers/ps3/Makefile
+++ b/drivers/ps3/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_PS3_VUART) += vuart.o
 obj-$(CONFIG_PS3_PS3AV) += ps3av.o ps3av_cmd.o
+obj-$(CONFIG_PS3_SYS_MANAGER) += sys-manager.o
diff --git a/drivers/ps3/sys-manager.c b/drivers/ps3/sys-manager.c
new file mode 100644
index 0000000..0fc30be
--- /dev/null
+++ b/drivers/ps3/sys-manager.c
@@ -0,0 +1,604 @@
+/*
+ *  PS3 System Manager.
+ *
+ *  Copyright (C) 2007 Sony Computer Entertainment Inc.
+ *  Copyright 2007 Sony Corp.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/reboot.h>
+#include <asm/ps3.h>
+#include "vuart.h"
+
+MODULE_AUTHOR("Sony Corporation");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PS3 System Manager");
+
+/**
+ * ps3_sys_manager - PS3 system manager driver.
+ *
+ * The system manager provides an asyncronous system event notification
+ * mechanism for reporting events like thermal alert and button presses to
+ * guests.  It also provides support to control system shutdown and startup.
+ *
+ * The actual system manager is implemented as an application running in the
+ * system policy module in lpar_1.  Guests communicate with the system manager
+ * through port 2 of the vuart using a simple packet message protocol.
+ * Messages are comprised of a fixed field header followed by a message
+ * specific payload.
+ */
+
+/**
+ * struct ps3_sys_manager_header - System manager message header.
+ * @version: Header version, currently 1.
+ * @size: Header size in bytes, curently 16.
+ * @payload_size: Message payload size in bytes.
+ * @service_id: Message type, one of enum ps3_sys_manager_service_id.
+ */
+
+struct ps3_sys_manager_header {
+	/* version 1 */
+	u8 version;
+	u8 size;
+	u16 reserved_1;
+	u32 payload_size;
+	u16 service_id;
+	u16 reserved_2[3];
+};
+
+/**
+ * @PS3_SM_RX_MSG_LEN - System manager received message length.
+ *
+ * Currently all messages received from the system manager are the same length
+ * (16 bytes header + 16 bytes payload = 32 bytes).  This knowlege is used to
+ * simplify the logic.
+ */
+
+enum {
+	PS3_SM_RX_MSG_LEN = 32,
+};
+
+/**
+ * enum ps3_sys_manager_service_id - Message header service_id.
+ * @PS3_SM_SERVICE_ID_REQUEST:      guest --> sys_manager.
+ * @PS3_SM_SERVICE_ID_COMMAND:      guest <-- sys_manager.
+ * @PS3_SM_SERVICE_ID_RESPONSE:     guest --> sys_manager.
+ * @PS3_SM_SERVICE_ID_SET_ATTR:     guest --> sys_manager.
+ * @PS3_SM_SERVICE_ID_EXTERN_EVENT: guest <-- sys_manager.
+ * @PS3_SM_SERVICE_ID_SET_NEXT_OP:  guest --> sys_manager.
+ */
+
+enum ps3_sys_manager_service_id {
+	/* version 1 */
+	PS3_SM_SERVICE_ID_REQUEST = 1,
+	PS3_SM_SERVICE_ID_RESPONSE = 2,
+	PS3_SM_SERVICE_ID_COMMAND = 3,
+	PS3_SM_SERVICE_ID_EXTERN_EVENT = 4,
+	PS3_SM_SERVICE_ID_SET_NEXT_OP = 5,
+	PS3_SM_SERVICE_ID_SET_ATTR = 8,
+};
+
+/**
+ * enum ps3_sys_manager_attr - Notification attribute (bit position mask).
+ * @PS3_SM_ATTR_POWER: Power button.
+ * @PS3_SM_ATTR_RESET: Reset button, not available on retail console.
+ * @PS3_SM_ATTR_THERMAL: Sytem thermal alert.
+ * @PS3_SM_ATTR_CONTROLLER: Remote controller event.
+ * @PS3_SM_ATTR_ALL: Logical OR of all.
+ *
+ * The guest tells the system manager which events it is interested in receiving
+ * notice of by sending the system manager a logical OR of notification
+ * attributes via the ps3_sys_manager_send_attr() routine.
+ */
+
+enum ps3_sys_manager_attr {
+	/* version 1 */
+	PS3_SM_ATTR_POWER = 1,
+	PS3_SM_ATTR_RESET = 2,
+	PS3_SM_ATTR_THERMAL = 4,
+	PS3_SM_ATTR_CONTROLLER = 8, /* bogus? */
+	PS3_SM_ATTR_ALL = 0x0f,
+};
+
+/**
+ * enum ps3_sys_manager_event - External event type, reported by system manager.
+ * @PS3_SM_EVENT_POWER_PRESSED: payload.value not used.
+ * @PS3_SM_EVENT_POWER_RELEASED: payload.value = time pressed in millisec.
+ * @PS3_SM_EVENT_RESET_PRESSED: payload.value not used.
+ * @PS3_SM_EVENT_RESET_RELEASED: payload.value = time pressed in millisec.
+ * @PS3_SM_EVENT_THERMAL_ALERT: payload.value = thermal zone id.
+ * @PS3_SM_EVENT_THERMAL_CLEARED: payload.value = thermal zone id.
+ */
+
+enum ps3_sys_manager_event {
+	/* version 1 */
+	PS3_SM_EVENT_POWER_PRESSED = 3,
+	PS3_SM_EVENT_POWER_RELEASED = 4,
+	PS3_SM_EVENT_RESET_PRESSED = 5,
+	PS3_SM_EVENT_RESET_RELEASED = 6,
+	PS3_SM_EVENT_THERMAL_ALERT = 7,
+	PS3_SM_EVENT_THERMAL_CLEARED = 8,
+	/* no info on controller events */
+};
+
+/**
+ * enum ps3_sys_manager_next_op - Operation to perform after lpar is destroyed.
+ */
+
+enum ps3_sys_manager_next_op {
+	/* version 3 */
+	PS3_SM_NEXT_OP_SYS_SHUTDOWN = 1,
+	PS3_SM_NEXT_OP_SYS_REBOOT = 2,
+	PS3_SM_NEXT_OP_LPAR_REBOOT = 0x82,
+};
+
+/**
+ * enum ps3_sys_manager_wake_source - Next-op wakeup source (bit position mask).
+ * @PS3_SM_WAKE_DEFAULT: Disk insert, power button, eject button, IR
+ * controller, and bluetooth controller.
+ * @PS3_SM_WAKE_RTC:
+ * @PS3_SM_WAKE_RTC_ERROR:
+ * @PS3_SM_WAKE_P_O_R: Power on reset.
+ *
+ * Additional wakeup sources when specifying PS3_SM_NEXT_OP_SYS_SHUTDOWN.
+ * System will always wake from the PS3_SM_WAKE_DEFAULT sources.
+ */
+
+enum ps3_sys_manager_wake_source {
+	/* version 3 */
+	PS3_SM_WAKE_DEFAULT   = 0,
+	PS3_SM_WAKE_RTC       = 0x00000040,
+	PS3_SM_WAKE_RTC_ERROR = 0x00000080,
+	PS3_SM_WAKE_P_O_R     = 0x10000000,
+};
+
+/**
+ * enum ps3_sys_manager_cmd - Command from system manager to guest.
+ *
+ * The guest completes the actions needed, then acks or naks the command via
+ * ps3_sys_manager_send_response().  In the case of @PS3_SM_CMD_SHUTDOWN,
+ * the guest must be fully prepared for a system poweroff prior to acking the
+ * command.
+ */
+
+enum ps3_sys_manager_cmd {
+	/* version 1 */
+	PS3_SM_CMD_SHUTDOWN = 1, /* shutdown guest OS */
+};
+
+/**
+ * ps3_sys_manager_write - Helper to write a two part message to the vuart.
+ *
+ */
+
+static int ps3_sys_manager_write(struct ps3_vuart_port_device *dev,
+	const struct ps3_sys_manager_header *header, const void *payload)
+{
+	int result;
+
+	BUG_ON(header->version != 1);
+	BUG_ON(header->size != 16);
+	BUG_ON(header->payload_size != 8 && header->payload_size != 16);
+	BUG_ON(header->service_id > 8);
+
+	result = ps3_vuart_write(dev, header,
+		sizeof(struct ps3_sys_manager_header));
+
+	if (!result)
+		result = ps3_vuart_write(dev, payload, header->payload_size);
+
+	return result;
+}
+
+/**
+ * ps3_sys_manager_send_attr - Send a 'set attribute' to the system manager.
+ *
+ */
+
+static int ps3_sys_manager_send_attr(struct ps3_vuart_port_device *dev,
+	enum ps3_sys_manager_attr attr)
+{
+	static const struct ps3_sys_manager_header header = {
+		.version = 1,
+		.size = 16,
+		.payload_size = 16,
+		.service_id = PS3_SM_SERVICE_ID_SET_ATTR,
+	};
+	struct {
+		u8 version;
+		u8 reserved_1[3];
+		u32 attribute;
+	} payload;
+
+	BUILD_BUG_ON(sizeof(payload) != 8);
+
+	dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, attr);
+
+	memset(&payload, 0, sizeof(payload));
+	payload.version = 1;
+	payload.attribute = attr;
+
+	return ps3_sys_manager_write(dev, &header, &payload);
+}
+
+/**
+ * ps3_sys_manager_send_next_op - Send a 'set next op' to the system manager.
+ *
+ * Tell the system manager what to do after this lpar is destroyed.
+ */
+
+static int ps3_sys_manager_send_next_op(struct ps3_vuart_port_device *dev,
+	enum ps3_sys_manager_next_op op,
+	enum ps3_sys_manager_wake_source wake_source)
+{
+	static const struct ps3_sys_manager_header header = {
+		.version = 1,
+		.size = 16,
+		.payload_size = 16,
+		.service_id = PS3_SM_SERVICE_ID_SET_NEXT_OP,
+	};
+	struct {
+		u8 version;
+		u8 type;
+		u8 gos_id;
+		u8 reserved_1;
+		u32 wake_source;
+		u8 reserved_2[8];
+	} payload;
+
+	BUILD_BUG_ON(sizeof(payload) != 16);
+
+	dev_dbg(&dev->core, "%s:%d: (%xh)\n", __func__, __LINE__, op);
+
+	memset(&payload, 0, sizeof(payload));
+	payload.version = 3;
+	payload.type = op;
+	payload.gos_id = 3; /* other os */
+	payload.wake_source = wake_source;
+
+	return ps3_sys_manager_write(dev, &header, &payload);
+}
+
+/**
+ * ps3_sys_manager_send_request_shutdown - Send 'request' to the system manager.
+ *
+ * The guest sends this message to request an operation or action of the system
+ * manager.  The reply is a command message from the system manager.  In the
+ * command handler the guest performs the requested operation.  The result of
+ * the command is then communicated back to the system manager with a response
+ * message.
+ *
+ * Currently, the only supported request it the 'shutdown self' request.
+ */
+
+static int ps3_sys_manager_send_request_shutdown(struct ps3_vuart_port_device *dev)
+{
+	static const struct ps3_sys_manager_header header = {
+		.version = 1,
+		.size = 16,
+		.payload_size = 16,
+		.service_id = PS3_SM_SERVICE_ID_REQUEST,
+	};
+	struct {
+		u8 version;
+		u8 type;
+		u8 gos_id;
+		u8 reserved_1[13];
+	} static const payload = {
+		.version = 1,
+		.type = 1, /* shutdown */
+		.gos_id = 0, /* self */
+	};
+
+	BUILD_BUG_ON(sizeof(payload) != 16);
+
+	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
+
+	return ps3_sys_manager_write(dev, &header, &payload);
+}
+
+/**
+ * ps3_sys_manager_send_response - Send a 'response' to the system manager.
+ * @status: zero = success, others fail.
+ *
+ * The guest sends this message to the system manager to acnowledge success or
+ * failure of a command sent by the system manager.
+ */
+
+static int ps3_sys_manager_send_response(struct ps3_vuart_port_device *dev,
+	u64 status)
+{
+	static const struct ps3_sys_manager_header header = {
+		.version = 1,
+		.size = 16,
+		.payload_size = 16,
+		.service_id = PS3_SM_SERVICE_ID_RESPONSE,
+	};
+	struct {
+		u8 version;
+		u8 reserved_1[3];
+		u8 status;
+		u8 reserved_2[11];
+	} payload;
+
+	BUILD_BUG_ON(sizeof(payload) != 16);
+
+	dev_dbg(&dev->core, "%s:%d: (%s)\n", __func__, __LINE__,
+		(status ? "nak" : "ack"));
+
+	memset(&payload, 0, sizeof(payload));
+	payload.version = 1;
+	payload.status = status;
+
+	return ps3_sys_manager_write(dev, &header, &payload);
+}
+
+/**
+ * ps3_sys_manager_handle_event - Second stage event msg handler.
+ *
+ */
+
+static int ps3_sys_manager_handle_event(struct ps3_vuart_port_device *dev)
+{
+	int result;
+	struct {
+		u8 version;
+		u8 type;
+		u8 reserved_1[2];
+		u32 value;
+		u8 reserved_2[8];
+	} event;
+
+	BUILD_BUG_ON(sizeof(event) != 16);
+
+	result = ps3_vuart_read(dev, &event, sizeof(event));
+	BUG_ON(result);
+
+	if (event.version != 1) {
+		dev_dbg(&dev->core, "%s:%d: unsupported event version (%u)\n",
+			__func__, __LINE__, event.version);
+		return -EIO;
+	}
+
+	switch (event.type) {
+	case PS3_SM_EVENT_POWER_PRESSED:
+		dev_dbg(&dev->core, "%s:%d: POWER_PRESSED\n",
+			__func__, __LINE__);
+		break;
+	case PS3_SM_EVENT_POWER_RELEASED:
+		dev_dbg(&dev->core, "%s:%d: POWER_RELEASED (%u ms)\n",
+			__func__, __LINE__, event.value);
+		kill_cad_pid(SIGINT, 1);
+		break;
+	case PS3_SM_EVENT_THERMAL_ALERT:
+		dev_dbg(&dev->core, "%s:%d: THERMAL_ALERT (zone %u)\n",
+			__func__, __LINE__, event.value);
+		printk(KERN_INFO "PS3 Thermal Alert Zone %u\n", event.value);
+		break;
+	case PS3_SM_EVENT_THERMAL_CLEARED:
+		dev_dbg(&dev->core, "%s:%d: THERMAL_CLEARED (zone %u)\n",
+			__func__, __LINE__, event.value);
+		break;
+	default:
+		dev_dbg(&dev->core, "%s:%d: unknown event (%u)\n",
+			__func__, __LINE__, event.type);
+		return -EIO;
+	}
+
+	return 0;
+}
+/**
+ * ps3_sys_manager_handle_cmd - Second stage command msg handler.
+ *
+ * The system manager sends this in reply to a 'request' message from the guest.
+ */
+
+static int ps3_sys_manager_handle_cmd(struct ps3_vuart_port_device *dev)
+{
+	int result;
+	struct {
+		u8 version;
+		u8 type;
+		u8 reserved_1[14];
+	} cmd;
+
+	BUILD_BUG_ON(sizeof(cmd) != 16);
+
+	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
+
+	result = ps3_vuart_read(dev, &cmd, sizeof(cmd));
+
+	if(result)
+		return result;
+
+	if (cmd.version != 1) {
+		dev_dbg(&dev->core, "%s:%d: unsupported cmd version (%u)\n",
+			__func__, __LINE__, cmd.version);
+		return -EIO;
+	}
+
+	if (cmd.type != PS3_SM_CMD_SHUTDOWN) {
+		dev_dbg(&dev->core, "%s:%d: unknown cmd (%u)\n",
+			__func__, __LINE__, cmd.type);
+		return -EIO;
+	}
+
+	ps3_sys_manager_send_response(dev, 0);
+	return 0;
+}
+
+/**
+ * ps3_sys_manager_handle_msg - First stage msg handler.
+ *
+ */
+
+static int ps3_sys_manager_handle_msg(struct ps3_vuart_port_device *dev)
+{
+	int result;
+	struct ps3_sys_manager_header header;
+
+	result = ps3_vuart_read(dev, &header,
+		sizeof(struct ps3_sys_manager_header));
+
+	if(result)
+		return result;
+
+	if (header.version != 1) {
+		dev_dbg(&dev->core, "%s:%d: unsupported header version (%u)\n",
+			__func__, __LINE__, header.version);
+		goto fail_header;
+	}
+
+	BUILD_BUG_ON(sizeof(header) != 16);
+	BUG_ON(header.size != 16);
+	BUG_ON(header.payload_size != 16);
+
+	switch (header.service_id) {
+	case PS3_SM_SERVICE_ID_EXTERN_EVENT:
+		dev_dbg(&dev->core, "%s:%d: EVENT\n", __func__, __LINE__);
+		return ps3_sys_manager_handle_event(dev);
+	case PS3_SM_SERVICE_ID_COMMAND:
+		dev_dbg(&dev->core, "%s:%d: COMMAND\n", __func__, __LINE__);
+		return ps3_sys_manager_handle_cmd(dev);
+	default:
+		dev_dbg(&dev->core, "%s:%d: unknown service_id (%u)\n",
+			__func__, __LINE__, header.service_id);
+		break;
+	}
+	goto fail_id;
+
+fail_header:
+	ps3_vuart_clear_rx_bytes(dev, 0);
+	return -EIO;
+fail_id:
+	ps3_vuart_clear_rx_bytes(dev, header.payload_size);
+	return -EIO;
+}
+
+/**
+ * ps3_sys_manager_work - Asyncronous read handler.
+ *
+ * Signaled when a complete message arrives at the vuart port.
+ */
+
+static void ps3_sys_manager_work(struct work_struct *work)
+{
+	struct ps3_vuart_port_device *dev = ps3_vuart_work_to_port_device(work);
+
+	ps3_sys_manager_handle_msg(dev);
+	ps3_vuart_read_async(dev, ps3_sys_manager_work, PS3_SM_RX_MSG_LEN);
+}
+
+struct {
+	struct ps3_vuart_port_device *dev;
+} static drv_priv;
+
+/**
+ * ps3_sys_manager_restart - The final platform machine_restart routine.
+ *
+ * This routine never returns.  The routine disables asyncronous vuart reads
+ * then spins calling ps3_sys_manager_handle_msg() to receive and acknowledge
+ * the shutdown command sent from the system manager.  Soon after the
+ * acknowledgement is sent the lpar is destroyed by the HV.  This routine
+ * should only be called from ps3_restart().
+ */
+
+void ps3_sys_manager_restart(void)
+{
+	struct ps3_vuart_port_device *dev = drv_priv.dev;
+
+	BUG_ON(!drv_priv.dev);
+
+	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
+
+	ps3_vuart_cancel_async(dev);
+
+	ps3_sys_manager_send_attr(dev, 0);
+	ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_LPAR_REBOOT,
+		PS3_SM_WAKE_DEFAULT);
+	ps3_sys_manager_send_request_shutdown(dev);
+
+	printk(KERN_EMERG "System Halted, OK to turn off power\n");
+
+	while(1)
+		ps3_sys_manager_handle_msg(dev);
+}
+
+/**
+ * ps3_sys_manager_power_off - The final platform machine_power_off routine.
+ *
+ * This routine never returns.  The routine disables asyncronous vuart reads
+ * then spins calling ps3_sys_manager_handle_msg() to receive and acknowledge
+ * the shutdown command sent from the system manager.  Soon after the
+ * acknowledgement is sent the lpar is destroyed by the HV.  This routine
+ * should only be called from ps3_power_off().
+ */
+
+void ps3_sys_manager_power_off(void)
+{
+	struct ps3_vuart_port_device *dev = drv_priv.dev;
+
+	BUG_ON(!drv_priv.dev);
+
+	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
+
+	ps3_vuart_cancel_async(dev);
+
+	ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_SHUTDOWN,
+		PS3_SM_WAKE_DEFAULT);
+	ps3_sys_manager_send_request_shutdown(dev);
+
+	printk(KERN_EMERG "System Halted, OK to turn off power\n");
+
+	while(1)
+		ps3_sys_manager_handle_msg(dev);
+}
+
+static int ps3_sys_manager_probe(struct ps3_vuart_port_device *dev)
+{
+	int result;
+
+	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
+
+	BUG_ON(drv_priv.dev);
+	drv_priv.dev = dev;
+
+	result = ps3_sys_manager_send_attr(dev, PS3_SM_ATTR_ALL);
+	BUG_ON(result);
+
+	result = ps3_vuart_read_async(dev, ps3_sys_manager_work,
+		PS3_SM_RX_MSG_LEN);
+	BUG_ON(result);
+
+	return result;
+}
+
+static struct ps3_vuart_port_driver ps3_sys_manager = {
+	.match_id = PS3_MATCH_ID_SYSTEM_MANAGER,
+	.core = {
+		.name = "ps3_sys_manager",
+	},
+	.probe = ps3_sys_manager_probe,
+};
+
+static int __init ps3_sys_manager_init(void)
+{
+	return ps3_vuart_port_driver_register(&ps3_sys_manager);
+}
+
+module_init(ps3_sys_manager_init);
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c
index ef8fd4c..7462981 100644
--- a/drivers/ps3/vuart.c
+++ b/drivers/ps3/vuart.c
@@ -21,8 +21,10 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/workqueue.h>
 #include <asm/ps3.h>
 
+#include <asm/firmware.h>
 #include <asm/lv1call.h>
 #include <asm/bitops.h>
 
@@ -30,7 +32,7 @@
 
 MODULE_AUTHOR("Sony Corporation");
 MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("ps3 vuart");
+MODULE_DESCRIPTION("PS3 vuart");
 
 /**
  * vuart - An inter-partition data link service.
@@ -157,7 +159,7 @@
 	unsigned long size;
 	unsigned long val;
 
-	result = lv1_get_virtual_uart_param(dev->port_number,
+	result = lv1_get_virtual_uart_param(dev->priv->port_number,
 		PARAM_TX_TRIGGER, &trig->tx);
 
 	if (result) {
@@ -166,7 +168,7 @@
 		return result;
 	}
 
-	result = lv1_get_virtual_uart_param(dev->port_number,
+	result = lv1_get_virtual_uart_param(dev->priv->port_number,
 		PARAM_RX_BUF_SIZE, &size);
 
 	if (result) {
@@ -175,7 +177,7 @@
 		return result;
 	}
 
-	result = lv1_get_virtual_uart_param(dev->port_number,
+	result = lv1_get_virtual_uart_param(dev->priv->port_number,
 		PARAM_RX_TRIGGER, &val);
 
 	if (result) {
@@ -198,7 +200,7 @@
 	int result;
 	unsigned long size;
 
-	result = lv1_set_virtual_uart_param(dev->port_number,
+	result = lv1_set_virtual_uart_param(dev->priv->port_number,
 		PARAM_TX_TRIGGER, tx);
 
 	if (result) {
@@ -207,7 +209,7 @@
 		return result;
 	}
 
-	result = lv1_get_virtual_uart_param(dev->port_number,
+	result = lv1_get_virtual_uart_param(dev->priv->port_number,
 		PARAM_RX_BUF_SIZE, &size);
 
 	if (result) {
@@ -216,7 +218,7 @@
 		return result;
 	}
 
-	result = lv1_set_virtual_uart_param(dev->port_number,
+	result = lv1_set_virtual_uart_param(dev->priv->port_number,
 		PARAM_RX_TRIGGER, size - rx);
 
 	if (result) {
@@ -232,9 +234,9 @@
 }
 
 static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device *dev,
-	unsigned long *bytes_waiting)
+	u64 *bytes_waiting)
 {
-	int result = lv1_get_virtual_uart_param(dev->port_number,
+	int result = lv1_get_virtual_uart_param(dev->priv->port_number,
 		PARAM_RX_BYTES, bytes_waiting);
 
 	if (result)
@@ -253,10 +255,10 @@
 
 	dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, mask);
 
-	dev->interrupt_mask = mask;
+	dev->priv->interrupt_mask = mask;
 
-	result = lv1_set_virtual_uart_param(dev->port_number,
-		PARAM_INTERRUPT_MASK, dev->interrupt_mask);
+	result = lv1_set_virtual_uart_param(dev->priv->port_number,
+		PARAM_INTERRUPT_MASK, dev->priv->interrupt_mask);
 
 	if (result)
 		dev_dbg(&dev->core, "%s:%d: interrupt_mask failed: %s\n",
@@ -265,62 +267,64 @@
 	return result;
 }
 
-static int ps3_vuart_get_interrupt_mask(struct ps3_vuart_port_device *dev,
+static int ps3_vuart_get_interrupt_status(struct ps3_vuart_port_device *dev,
 	unsigned long *status)
 {
-	int result = lv1_get_virtual_uart_param(dev->port_number,
-		PARAM_INTERRUPT_STATUS, status);
+	u64 tmp;
+	int result = lv1_get_virtual_uart_param(dev->priv->port_number,
+		PARAM_INTERRUPT_STATUS, &tmp);
 
 	if (result)
 		dev_dbg(&dev->core, "%s:%d: interrupt_status failed: %s\n",
 			__func__, __LINE__, ps3_result(result));
 
+	*status = tmp & dev->priv->interrupt_mask;
+
 	dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n",
-		__func__, __LINE__, dev->interrupt_mask, *status,
-		dev->interrupt_mask & *status);
+		__func__, __LINE__, dev->priv->interrupt_mask, tmp, *status);
 
 	return result;
 }
 
 int ps3_vuart_enable_interrupt_tx(struct ps3_vuart_port_device *dev)
 {
-	return (dev->interrupt_mask & INTERRUPT_MASK_TX) ? 0
-		: ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask
+	return (dev->priv->interrupt_mask & INTERRUPT_MASK_TX) ? 0
+		: ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
 		| INTERRUPT_MASK_TX);
 }
 
 int ps3_vuart_enable_interrupt_rx(struct ps3_vuart_port_device *dev)
 {
-	return (dev->interrupt_mask & INTERRUPT_MASK_RX) ? 0
-		: ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask
+	return (dev->priv->interrupt_mask & INTERRUPT_MASK_RX) ? 0
+		: ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
 		| INTERRUPT_MASK_RX);
 }
 
 int ps3_vuart_enable_interrupt_disconnect(struct ps3_vuart_port_device *dev)
 {
-	return (dev->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0
-		: ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask
+	return (dev->priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0
+		: ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
 		| INTERRUPT_MASK_DISCONNECT);
 }
 
 int ps3_vuart_disable_interrupt_tx(struct ps3_vuart_port_device *dev)
 {
-	return (dev->interrupt_mask & INTERRUPT_MASK_TX)
-		? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask
+	return (dev->priv->interrupt_mask & INTERRUPT_MASK_TX)
+		? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
 		& ~INTERRUPT_MASK_TX) : 0;
 }
 
 int ps3_vuart_disable_interrupt_rx(struct ps3_vuart_port_device *dev)
 {
-	return (dev->interrupt_mask & INTERRUPT_MASK_RX)
-		? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask
+	return (dev->priv->interrupt_mask & INTERRUPT_MASK_RX)
+		? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
 		& ~INTERRUPT_MASK_RX) : 0;
 }
 
 int ps3_vuart_disable_interrupt_disconnect(struct ps3_vuart_port_device *dev)
 {
-	return (dev->interrupt_mask & INTERRUPT_MASK_DISCONNECT)
-		? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask
+	return (dev->priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT)
+		? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
 		& ~INTERRUPT_MASK_DISCONNECT) : 0;
 }
 
@@ -335,9 +339,7 @@
 {
 	int result;
 
-	dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes);
-
-	result = lv1_write_virtual_uart(dev->port_number,
+	result = lv1_write_virtual_uart(dev->priv->port_number,
 		ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_written);
 
 	if (result) {
@@ -346,10 +348,10 @@
 		return result;
 	}
 
-	dev->stats.bytes_written += *bytes_written;
+	dev->priv->stats.bytes_written += *bytes_written;
 
-	dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__,
-		__LINE__, *bytes_written, bytes, dev->stats.bytes_written);
+	dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, __LINE__,
+		*bytes_written, bytes, dev->priv->stats.bytes_written);
 
 	return result;
 }
@@ -367,7 +369,7 @@
 
 	dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes);
 
-	result = lv1_read_virtual_uart(dev->port_number,
+	result = lv1_read_virtual_uart(dev->priv->port_number,
 		ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_read);
 
 	if (result) {
@@ -376,15 +378,58 @@
 		return result;
 	}
 
-	dev->stats.bytes_read += *bytes_read;
+	dev->priv->stats.bytes_read += *bytes_read;
 
 	dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__,
-		*bytes_read, bytes, dev->stats.bytes_read);
+		*bytes_read, bytes, dev->priv->stats.bytes_read);
 
 	return result;
 }
 
 /**
+ * ps3_vuart_clear_rx_bytes - Discard bytes received.
+ * @bytes: Max byte count to discard, zero = all pending.
+ *
+ * Used to clear pending rx interrupt source.  Will not block.
+ */
+
+void ps3_vuart_clear_rx_bytes(struct ps3_vuart_port_device *dev,
+	unsigned int bytes)
+{
+	int result;
+	u64 bytes_waiting;
+	void* tmp;
+
+	result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes_waiting);
+
+	BUG_ON(result);
+
+	bytes = bytes ? min(bytes, (unsigned int)bytes_waiting) : bytes_waiting;
+
+	dev_dbg(&dev->core, "%s:%d: %u\n", __func__, __LINE__, bytes);
+
+	if (!bytes)
+		return;
+
+	/* Add some extra space for recently arrived data. */
+
+	bytes += 128;
+
+	tmp = kmalloc(bytes, GFP_KERNEL);
+
+	if (!tmp)
+		return;
+
+	ps3_vuart_raw_read(dev, tmp, bytes, &bytes_waiting);
+
+	kfree(tmp);
+
+	/* Don't include these bytes in the stats. */
+
+	dev->priv->stats.bytes_read -= bytes_waiting;
+}
+
+/**
  * struct list_buffer - An element for a port device fifo buffer list.
  */
 
@@ -416,14 +461,14 @@
 	dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
 		bytes, bytes);
 
-	spin_lock_irqsave(&dev->tx_list.lock, flags);
+	spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
 
-	if (list_empty(&dev->tx_list.head)) {
+	if (list_empty(&dev->priv->tx_list.head)) {
 		unsigned long bytes_written;
 
 		result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written);
 
-		spin_unlock_irqrestore(&dev->tx_list.lock, flags);
+		spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
 
 		if (result) {
 			dev_dbg(&dev->core,
@@ -441,7 +486,7 @@
 		bytes -= bytes_written;
 		buf += bytes_written;
 	} else
-		spin_unlock_irqrestore(&dev->tx_list.lock, flags);
+		spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
 
 	lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL);
 
@@ -454,10 +499,10 @@
 	lb->tail = lb->data + bytes;
 	lb->dbg_number = ++dbg_number;
 
-	spin_lock_irqsave(&dev->tx_list.lock, flags);
-	list_add_tail(&lb->link, &dev->tx_list.head);
+	spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
+	list_add_tail(&lb->link, &dev->priv->tx_list.head);
 	ps3_vuart_enable_interrupt_tx(dev);
-	spin_unlock_irqrestore(&dev->tx_list.lock, flags);
+	spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
 
 	dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %xh bytes\n",
 		__func__, __LINE__, lb->dbg_number, bytes);
@@ -484,47 +529,83 @@
 	dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
 		bytes, bytes);
 
-	spin_lock_irqsave(&dev->rx_list.lock, flags);
+	spin_lock_irqsave(&dev->priv->rx_list.lock, flags);
 
-	if (dev->rx_list.bytes_held < bytes) {
-		spin_unlock_irqrestore(&dev->rx_list.lock, flags);
+	if (dev->priv->rx_list.bytes_held < bytes) {
+		spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
 		dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n",
-			__func__, __LINE__, bytes - dev->rx_list.bytes_held);
+			__func__, __LINE__,
+			bytes - dev->priv->rx_list.bytes_held);
 		return -EAGAIN;
 	}
 
-	list_for_each_entry_safe(lb, n, &dev->rx_list.head, link) {
+	list_for_each_entry_safe(lb, n, &dev->priv->rx_list.head, link) {
 		bytes_read = min((unsigned int)(lb->tail - lb->head), bytes);
 
 		memcpy(buf, lb->head, bytes_read);
 		buf += bytes_read;
 		bytes -= bytes_read;
-		dev->rx_list.bytes_held -= bytes_read;
+		dev->priv->rx_list.bytes_held -= bytes_read;
 
 		if (bytes_read < lb->tail - lb->head) {
 			lb->head += bytes_read;
-			spin_unlock_irqrestore(&dev->rx_list.lock, flags);
-
-			dev_dbg(&dev->core,
-				"%s:%d: dequeued buf_%lu, %lxh bytes\n",
-				__func__, __LINE__, lb->dbg_number, bytes_read);
+			dev_dbg(&dev->core, "%s:%d: buf_%lu: dequeued %lxh "
+				"bytes\n", __func__, __LINE__, lb->dbg_number,
+				bytes_read);
+			spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
 			return 0;
 		}
 
-		dev_dbg(&dev->core, "%s:%d free buf_%lu\n", __func__, __LINE__,
-			lb->dbg_number);
+		dev_dbg(&dev->core, "%s:%d: buf_%lu: free, dequeued %lxh "
+			"bytes\n", __func__, __LINE__, lb->dbg_number,
+			bytes_read);
 
 		list_del(&lb->link);
 		kfree(lb);
 	}
-	spin_unlock_irqrestore(&dev->rx_list.lock, flags);
 
-	dev_dbg(&dev->core, "%s:%d: dequeued buf_%lu, %xh bytes\n",
-		__func__, __LINE__, lb->dbg_number, bytes);
+	spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
+	return 0;
+}
+
+int ps3_vuart_read_async(struct ps3_vuart_port_device *dev, work_func_t func,
+	unsigned int bytes)
+{
+	unsigned long flags;
+
+	if(dev->priv->work.trigger) {
+		dev_dbg(&dev->core, "%s:%d: warning, multiple calls\n",
+			__func__, __LINE__);
+		return -EAGAIN;
+	}
+
+	BUG_ON(!bytes);
+
+	PREPARE_WORK(&dev->priv->work.work, func);
+
+	spin_lock_irqsave(&dev->priv->work.lock, flags);
+	if(dev->priv->rx_list.bytes_held >= bytes) {
+		dev_dbg(&dev->core, "%s:%d: schedule_work %xh bytes\n",
+			__func__, __LINE__, bytes);
+		schedule_work(&dev->priv->work.work);
+		spin_unlock_irqrestore(&dev->priv->work.lock, flags);
+		return 0;
+	}
+
+	dev->priv->work.trigger = bytes;
+	spin_unlock_irqrestore(&dev->priv->work.lock, flags);
+
+	dev_dbg(&dev->core, "%s:%d: waiting for %u(%xh) bytes\n", __func__,
+		__LINE__, bytes, bytes);
 
 	return 0;
 }
 
+void ps3_vuart_cancel_async(struct ps3_vuart_port_device *dev)
+{
+	dev->priv->work.trigger = 0;
+}
+
 /**
  * ps3_vuart_handle_interrupt_tx - third stage transmit interrupt handler
  *
@@ -542,9 +623,9 @@
 
 	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
 
-	spin_lock_irqsave(&dev->tx_list.lock, flags);
+	spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
 
-	list_for_each_entry_safe(lb, n, &dev->tx_list.head, link) {
+	list_for_each_entry_safe(lb, n, &dev->priv->tx_list.head, link) {
 
 		unsigned long bytes_written;
 
@@ -578,7 +659,7 @@
 
 	ps3_vuart_disable_interrupt_tx(dev);
 port_full:
-	spin_unlock_irqrestore(&dev->tx_list.lock, flags);
+	spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
 	dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n",
 		__func__, __LINE__, bytes_total);
 	return result;
@@ -609,7 +690,7 @@
 
 	BUG_ON(!bytes);
 
-	/* add some extra space for recently arrived data */
+	/* Add some extra space for recently arrived data. */
 
 	bytes += 128;
 
@@ -624,14 +705,23 @@
 	lb->tail = lb->data + bytes;
 	lb->dbg_number = ++dbg_number;
 
-	spin_lock_irqsave(&dev->rx_list.lock, flags);
-	list_add_tail(&lb->link, &dev->rx_list.head);
-	dev->rx_list.bytes_held += bytes;
-	spin_unlock_irqrestore(&dev->rx_list.lock, flags);
+	spin_lock_irqsave(&dev->priv->rx_list.lock, flags);
+	list_add_tail(&lb->link, &dev->priv->rx_list.head);
+	dev->priv->rx_list.bytes_held += bytes;
+	spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
 
-	dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %lxh bytes\n",
+	dev_dbg(&dev->core, "%s:%d: buf_%lu: queued %lxh bytes\n",
 		__func__, __LINE__, lb->dbg_number, bytes);
 
+	spin_lock_irqsave(&dev->priv->work.lock, flags);
+	if(dev->priv->work.trigger
+		&& dev->priv->rx_list.bytes_held >= dev->priv->work.trigger) {
+		dev_dbg(&dev->core, "%s:%d: schedule_work %lxh bytes\n",
+			__func__, __LINE__, dev->priv->work.trigger);
+		dev->priv->work.trigger = 0;
+		schedule_work(&dev->priv->work.work);
+	}
+	spin_unlock_irqrestore(&dev->priv->work.lock, flags);
 	return 0;
 }
 
@@ -656,7 +746,7 @@
 	int result;
 	unsigned long status;
 
-	result = ps3_vuart_get_interrupt_mask(dev, &status);
+	result = ps3_vuart_get_interrupt_status(dev, &status);
 
 	if (result)
 		return result;
@@ -665,21 +755,21 @@
 		status);
 
 	if (status & INTERRUPT_MASK_DISCONNECT) {
-		dev->stats.disconnect_interrupts++;
+		dev->priv->stats.disconnect_interrupts++;
 		result = ps3_vuart_handle_interrupt_disconnect(dev);
 		if (result)
 			ps3_vuart_disable_interrupt_disconnect(dev);
 	}
 
 	if (status & INTERRUPT_MASK_TX) {
-		dev->stats.tx_interrupts++;
+		dev->priv->stats.tx_interrupts++;
 		result = ps3_vuart_handle_interrupt_tx(dev);
 		if (result)
 			ps3_vuart_disable_interrupt_tx(dev);
 	}
 
 	if (status & INTERRUPT_MASK_RX) {
-		dev->stats.rx_interrupts++;
+		dev->priv->stats.rx_interrupts++;
 		result = ps3_vuart_handle_interrupt_rx(dev);
 		if (result)
 			ps3_vuart_disable_interrupt_rx(dev);
@@ -688,12 +778,13 @@
 	return 0;
 }
 
-struct vuart_private {
-	unsigned int in_use;
-	unsigned int virq;
-	struct ps3_vuart_port_device *devices[PORT_COUNT];
+struct vuart_bus_priv {
 	const struct ports_bmp bmp;
-};
+	unsigned int virq;
+	struct semaphore probe_mutex;
+	int use_count;
+	struct ps3_vuart_port_device *devices[PORT_COUNT];
+} static vuart_bus_priv;
 
 /**
  * ps3_vuart_irq_handler - first stage interrupt handler
@@ -705,25 +796,25 @@
 
 static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private)
 {
-	struct vuart_private *private;
+	struct vuart_bus_priv *bus_priv;
 
 	BUG_ON(!_private);
-	private = (struct vuart_private *)_private;
+	bus_priv = (struct vuart_bus_priv *)_private;
 
 	while (1) {
 		unsigned int port;
 
-		dump_ports_bmp(&private->bmp);
+		dump_ports_bmp(&bus_priv->bmp);
 
-		port = (BITS_PER_LONG - 1) - __ilog2(private->bmp.status);
+		port = (BITS_PER_LONG - 1) - __ilog2(bus_priv->bmp.status);
 
 		if (port == BITS_PER_LONG)
 			break;
 
 		BUG_ON(port >= PORT_COUNT);
-		BUG_ON(!private->devices[port]);
+		BUG_ON(!bus_priv->devices[port]);
 
-		ps3_vuart_handle_port_interrupt(private->devices[port]);
+		ps3_vuart_handle_port_interrupt(bus_priv->devices[port]);
 	}
 
 	return IRQ_HANDLED;
@@ -744,12 +835,10 @@
 	return result;
 }
 
-static struct vuart_private vuart_private;
-
 static int ps3_vuart_probe(struct device *_dev)
 {
 	int result;
-	unsigned long tmp;
+	unsigned int port_number;
 	struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
 	struct ps3_vuart_port_driver *drv =
 		to_ps3_vuart_port_driver(_dev->driver);
@@ -758,7 +847,12 @@
 
 	BUG_ON(!drv);
 
-	result = ps3_vuart_match_id_to_port(dev->match_id, &dev->port_number);
+	down(&vuart_bus_priv.probe_mutex);
+
+	/* Setup vuart_bus_priv.devices[]. */
+
+	result = ps3_vuart_match_id_to_port(dev->match_id,
+		&port_number);
 
 	if (result) {
 		dev_dbg(&dev->core, "%s:%d: unknown match_id (%d)\n",
@@ -767,24 +861,41 @@
 		goto fail_match;
 	}
 
-	if (vuart_private.devices[dev->port_number]) {
+	if (vuart_bus_priv.devices[port_number]) {
 		dev_dbg(&dev->core, "%s:%d: port busy (%d)\n", __func__,
-			__LINE__, dev->port_number);
+			__LINE__, port_number);
 		result = -EBUSY;
 		goto fail_match;
 	}
 
-	vuart_private.devices[dev->port_number] = dev;
+	vuart_bus_priv.devices[port_number] = dev;
 
-	INIT_LIST_HEAD(&dev->tx_list.head);
-	spin_lock_init(&dev->tx_list.lock);
-	INIT_LIST_HEAD(&dev->rx_list.head);
-	spin_lock_init(&dev->rx_list.lock);
+	/* Setup dev->priv. */
 
-	vuart_private.in_use++;
-	if (vuart_private.in_use == 1) {
+	dev->priv = kzalloc(sizeof(struct ps3_vuart_port_priv), GFP_KERNEL);
+
+	if (!dev->priv) {
+		result = -ENOMEM;
+		goto fail_alloc;
+	}
+
+	dev->priv->port_number = port_number;
+
+	INIT_LIST_HEAD(&dev->priv->tx_list.head);
+	spin_lock_init(&dev->priv->tx_list.lock);
+
+	INIT_LIST_HEAD(&dev->priv->rx_list.head);
+	spin_lock_init(&dev->priv->rx_list.lock);
+
+	INIT_WORK(&dev->priv->work.work, NULL);
+	spin_lock_init(&dev->priv->work.lock);
+	dev->priv->work.trigger = 0;
+	dev->priv->work.dev = dev;
+
+	if (++vuart_bus_priv.use_count == 1) {
+
 		result = ps3_alloc_vuart_irq(PS3_BINDING_CPU_ANY,
-			(void*)&vuart_private.bmp.status, &vuart_private.virq);
+			(void*)&vuart_bus_priv.bmp.status, &vuart_bus_priv.virq);
 
 		if (result) {
 			dev_dbg(&dev->core,
@@ -794,8 +905,8 @@
 			goto fail_alloc_irq;
 		}
 
-		result = request_irq(vuart_private.virq, ps3_vuart_irq_handler,
-			IRQF_DISABLED, "vuart", &vuart_private);
+		result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler,
+			IRQF_DISABLED, "vuart", &vuart_bus_priv);
 
 		if (result) {
 			dev_info(&dev->core, "%s:%d: request_irq failed (%d)\n",
@@ -804,10 +915,11 @@
 		}
 	}
 
-	ps3_vuart_set_interrupt_mask(dev, INTERRUPT_MASK_RX);
-
 	/* clear stale pending interrupts */
-	ps3_vuart_get_interrupt_mask(dev, &tmp);
+
+	ps3_vuart_clear_rx_bytes(dev, 0);
+
+	ps3_vuart_set_interrupt_mask(dev, INTERRUPT_MASK_RX);
 
 	ps3_vuart_set_triggers(dev, 1, 1);
 
@@ -822,20 +934,27 @@
 	if (result) {
 		dev_dbg(&dev->core, "%s:%d: drv->probe failed\n",
 			__func__, __LINE__);
+		down(&vuart_bus_priv.probe_mutex);
 		goto fail_probe;
 	}
 
+	up(&vuart_bus_priv.probe_mutex);
+
 	return result;
 
 fail_probe:
+	ps3_vuart_set_interrupt_mask(dev, 0);
 fail_request_irq:
-	vuart_private.in_use--;
-	if (!vuart_private.in_use) {
-		ps3_free_vuart_irq(vuart_private.virq);
-		vuart_private.virq = NO_IRQ;
-	}
+	ps3_free_vuart_irq(vuart_bus_priv.virq);
+	vuart_bus_priv.virq = NO_IRQ;
 fail_alloc_irq:
+	--vuart_bus_priv.use_count;
+	kfree(dev->priv);
+	dev->priv = NULL;
+fail_alloc:
+	vuart_bus_priv.devices[port_number] = 0;
 fail_match:
+	up(&vuart_bus_priv.probe_mutex);
 	dev_dbg(&dev->core, "%s:%d failed\n", __func__, __LINE__);
 	return result;
 }
@@ -846,10 +965,12 @@
 	struct ps3_vuart_port_driver *drv =
 		to_ps3_vuart_port_driver(_dev->driver);
 
+	down(&vuart_bus_priv.probe_mutex);
+
 	dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__,
 		dev->core.bus_id);
 
-	BUG_ON(vuart_private.in_use < 1);
+	BUG_ON(vuart_bus_priv.use_count < 1);
 
 	if (drv->remove)
 		drv->remove(dev);
@@ -857,13 +978,19 @@
 		dev_dbg(&dev->core, "%s:%d: %s no remove method\n", __func__,
 			__LINE__, dev->core.bus_id);
 
-	vuart_private.in_use--;
+	vuart_bus_priv.devices[dev->priv->port_number] = 0;
 
-	if (!vuart_private.in_use) {
-		free_irq(vuart_private.virq, &vuart_private);
-		ps3_free_vuart_irq(vuart_private.virq);
-		vuart_private.virq = NO_IRQ;
+	if (--vuart_bus_priv.use_count == 0) {
+		BUG();
+		free_irq(vuart_bus_priv.virq, &vuart_bus_priv);
+		ps3_free_vuart_irq(vuart_bus_priv.virq);
+		vuart_bus_priv.virq = NO_IRQ;
 	}
+
+	kfree(dev->priv);
+	dev->priv = NULL;
+
+	up(&vuart_bus_priv.probe_mutex);
 	return 0;
 }
 
@@ -884,12 +1011,12 @@
 }
 
 /**
- * ps3_vuart - The vuart instance.
+ * ps3_vuart_bus - The vuart bus instance.
  *
  * The vuart is managed as a bus that port devices connect to.
  */
 
-struct bus_type ps3_vuart = {
+struct bus_type ps3_vuart_bus = {
         .name = "ps3_vuart",
 	.match = ps3_vuart_match,
 	.probe = ps3_vuart_probe,
@@ -897,24 +1024,30 @@
 	.shutdown = ps3_vuart_shutdown,
 };
 
-int __init ps3_vuart_init(void)
+int __init ps3_vuart_bus_init(void)
 {
 	int result;
 
 	pr_debug("%s:%d:\n", __func__, __LINE__);
-	result = bus_register(&ps3_vuart);
+
+	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+		return 0;
+
+	init_MUTEX(&vuart_bus_priv.probe_mutex);
+	result = bus_register(&ps3_vuart_bus);
 	BUG_ON(result);
+
 	return result;
 }
 
-void __exit ps3_vuart_exit(void)
+void __exit ps3_vuart_bus_exit(void)
 {
 	pr_debug("%s:%d:\n", __func__, __LINE__);
-	bus_unregister(&ps3_vuart);
+	bus_unregister(&ps3_vuart_bus);
 }
 
-core_initcall(ps3_vuart_init);
-module_exit(ps3_vuart_exit);
+core_initcall(ps3_vuart_bus_init);
+module_exit(ps3_vuart_bus_exit);
 
 /**
  * ps3_vuart_port_release_device - Remove a vuart port device.
@@ -922,11 +1055,14 @@
 
 static void ps3_vuart_port_release_device(struct device *_dev)
 {
-	struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
 #if defined(DEBUG)
-	memset(dev, 0xad, sizeof(struct ps3_vuart_port_device));
+	struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
+
+	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
+
+	BUG_ON(dev->priv && "forgot to free");
+	memset(&dev->core, 0, sizeof(dev->core));
 #endif
-	kfree(dev);
 }
 
 /**
@@ -935,11 +1071,12 @@
 
 int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev)
 {
-	int result;
 	static unsigned int dev_count = 1;
 
+	BUG_ON(dev->priv && "forgot to free");
+
 	dev->core.parent = NULL;
-	dev->core.bus = &ps3_vuart;
+	dev->core.bus = &ps3_vuart_bus;
 	dev->core.release = ps3_vuart_port_release_device;
 
 	snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "vuart_%02x",
@@ -947,9 +1084,7 @@
 
 	dev_dbg(&dev->core, "%s:%d register\n", __func__, __LINE__);
 
-	result = device_register(&dev->core);
-
-	return result;
+	return device_register(&dev->core);
 }
 
 EXPORT_SYMBOL_GPL(ps3_vuart_port_device_register);
@@ -963,7 +1098,7 @@
 	int result;
 
 	pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name);
-	drv->core.bus = &ps3_vuart;
+	drv->core.bus = &ps3_vuart_bus;
 	result = driver_register(&drv->core);
 	return result;
 }
@@ -976,6 +1111,7 @@
 
 void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv)
 {
+	pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name);
 	driver_unregister(&drv->core);
 }
 
diff --git a/drivers/ps3/vuart.h b/drivers/ps3/vuart.h
index 2cbf728..1be992d 100644
--- a/drivers/ps3/vuart.h
+++ b/drivers/ps3/vuart.h
@@ -21,6 +21,44 @@
 #if !defined(_PS3_VUART_H)
 #define _PS3_VUART_H
 
+#include <asm/ps3.h>
+
+struct ps3_vuart_stats {
+	unsigned long bytes_written;
+	unsigned long bytes_read;
+	unsigned long tx_interrupts;
+	unsigned long rx_interrupts;
+	unsigned long disconnect_interrupts;
+};
+
+struct ps3_vuart_work {
+	struct work_struct work;
+	unsigned long trigger;
+	spinlock_t lock;
+	struct ps3_vuart_port_device* dev; /* to convert work to device */
+};
+
+/**
+ * struct ps3_vuart_port_priv - private vuart device data.
+ */
+
+struct ps3_vuart_port_priv {
+	unsigned int port_number;
+	u64 interrupt_mask;
+
+	struct {
+		spinlock_t lock;
+		struct list_head head;
+	} tx_list;
+	struct {
+		unsigned long bytes_held;
+		spinlock_t lock;
+		struct list_head head;
+	} rx_list;
+	struct ps3_vuart_stats stats;
+	struct ps3_vuart_work work;
+};
+
 /**
  * struct ps3_vuart_port_driver - a driver for a device on a vuart port
  */
@@ -41,10 +79,6 @@
 int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv);
 void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv);
 
-int ps3_vuart_write(struct ps3_vuart_port_device *dev,
-	const void* buf, unsigned int bytes);
-int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf,
-	unsigned int bytes);
 static inline struct ps3_vuart_port_driver *to_ps3_vuart_port_driver(
 	struct device_driver *_drv)
 {
@@ -55,5 +89,22 @@
 {
 	return container_of(_dev, struct ps3_vuart_port_device, core);
 }
+static inline struct ps3_vuart_port_device *ps3_vuart_work_to_port_device(
+	struct work_struct *_work)
+{
+	struct ps3_vuart_work *vw = container_of(_work, struct ps3_vuart_work,
+		work);
+	return vw->dev;
+}
+
+int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
+	unsigned int bytes);
+int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf,
+	unsigned int bytes);
+int ps3_vuart_read_async(struct ps3_vuart_port_device *dev, work_func_t func,
+	unsigned int bytes);
+void ps3_vuart_cancel_async(struct ps3_vuart_port_device *dev);
+void ps3_vuart_clear_rx_bytes(struct ps3_vuart_port_device *dev,
+	unsigned int bytes);
 
 #endif
diff --git a/drivers/sbus/char/vfc_i2c.c b/drivers/sbus/char/vfc_i2c.c
index ceec306..9efed77 100644
--- a/drivers/sbus/char/vfc_i2c.c
+++ b/drivers/sbus/char/vfc_i2c.c
@@ -14,7 +14,7 @@
 /* NOTE: It seems to me that the documentation regarding the
 pcd8584t/pcf8584 does not show the correct way to address the i2c bus.
 Based on the information on the I2C bus itself and the remainder of
-the Phillips docs the following algorithims apper to be correct.  I am
+the Phillips docs the following algorithms appear to be correct.  I am
 fairly certain that the flowcharts in the phillips docs are wrong. */
 
 
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 5bf3f07..4cd280e 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -230,6 +230,7 @@
 	  The SCSI subsystem can probe for devices while the rest of the
 	  system continues booting, and even probe devices on different
 	  busses in parallel, leading to a significant speed-up.
+
 	  If you have built SCSI as modules, enabling this option can
 	  be a problem as the devices may not have been found by the
 	  time your system expects them to have been.  You can load the
@@ -237,8 +238,8 @@
 	  If you build your SCSI drivers into the kernel, then everything
 	  will work fine if you say Y here.
 
-	  You can override this choice by specifying scsi_mod.scan="sync"
-	  or "async" on the kernel's command line.
+	  You can override this choice by specifying "scsi_mod.scan=sync"
+	  or async on the kernel's command line.
 
 menu "SCSI Transports"
 	depends on SCSI
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index 2650a5d..7f4241b 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -1067,7 +1067,7 @@
 		goto out_disable_device;
 	}
 
-	/* <02> read from base address + 0x50 offset to get the bios balue. */
+	/* <02> read from base address + 0x50 offset to get the bios value. */
 	bios = ORC_RDWORD(port, 0x50);
 
 
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index c7fe478..2be03e9 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -418,7 +418,6 @@
 	strcat(bp, "        ");
 	ahd_controller_info(ahd, ahd_info);
 	strcat(bp, ahd_info);
-	strcat(bp, "\n");
 
 	return (bp);
 }
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c
index eae7a24..c750fbf 100644
--- a/drivers/scsi/aic94xx/aic94xx_seq.c
+++ b/drivers/scsi/aic94xx/aic94xx_seq.c
@@ -44,7 +44,6 @@
 #define PAUSE_TRIES 1000
 
 static const struct firmware *sequencer_fw;
-static const char *sequencer_version;
 static u16 cseq_vecs[CSEQ_NUM_VECS], lseq_vecs[LSEQ_NUM_VECS], mode2_task,
 	cseq_idle_loop, lseq_idle_loop;
 static u8 *cseq_code, *lseq_code;
@@ -1276,7 +1275,6 @@
 	header.csum = le32_to_cpu(hdr_ptr->csum);
 	header.major = le32_to_cpu(hdr_ptr->major);
 	header.minor = le32_to_cpu(hdr_ptr->minor);
-	sequencer_version = hdr_ptr->version;
 	header.cseq_table_offset = le32_to_cpu(hdr_ptr->cseq_table_offset);
 	header.cseq_table_size = le32_to_cpu(hdr_ptr->cseq_table_size);
 	header.lseq_table_offset = le32_to_cpu(hdr_ptr->lseq_table_offset);
@@ -1303,6 +1301,16 @@
 		return -EINVAL;
 	}
 
+	asd_printk("Found sequencer Firmware version %d.%d (%s)\n",
+		   header.major, header.minor, hdr_ptr->version);
+
+	if (header.major != SAS_RAZOR_SEQUENCER_FW_MAJOR) {
+		asd_printk("Firmware Major Version Mismatch;"
+			   "driver requires version %d.X",
+			   SAS_RAZOR_SEQUENCER_FW_MAJOR);
+		return -EINVAL;
+	}
+
 	ptr_cseq_vecs = (u16 *)&sequencer_fw->data[header.cseq_table_offset];
 	ptr_lseq_vecs = (u16 *)&sequencer_fw->data[header.lseq_table_offset];
 	mode2_task = header.mode2_task;
@@ -1335,7 +1343,6 @@
 		return err;
 	}
 
-	asd_printk("using sequencer %s\n", sequencer_version);
 	err = asd_seq_download_seqs(asd_ha);
 	if (err) {
 		asd_printk("couldn't download sequencers for %s\n",
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.h b/drivers/scsi/aic94xx/aic94xx_seq.h
index 9437ff0..2ea6a0d 100644
--- a/drivers/scsi/aic94xx/aic94xx_seq.h
+++ b/drivers/scsi/aic94xx/aic94xx_seq.h
@@ -31,6 +31,7 @@
 #define LSEQ_NUM_VECS	11
 
 #define SAS_RAZOR_SEQUENCER_FW_FILE "aic94xx-seq.fw"
+#define SAS_RAZOR_SEQUENCER_FW_MAJOR	1
 
 /* Note:  All quantites in the sequencer file are little endian */
 struct sequencer_file_header {
diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c
index 4677152..d413652 100644
--- a/drivers/scsi/arm/eesox.c
+++ b/drivers/scsi/arm/eesox.c
@@ -196,7 +196,7 @@
 	const void __iomem *reg_fas = base + EESOX_FAS216_OFFSET;
 	const void __iomem *reg_dmastat = base + EESOX_DMASTAT;
 	const void __iomem *reg_dmadata = base + EESOX_DMADATA;
-	const register unsigned long mask = 0xffff;
+	register const unsigned long mask = 0xffff;
 
 	do {
 		unsigned int status;
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 8f6b5bf..2b5b8a9 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -801,15 +801,10 @@
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
 	struct ide_scsi_obj *scsi;
-	ide_drive_t *drive;
 
 	if (!(scsi = ide_scsi_get(disk)))
 		return -ENXIO;
 
-	drive = scsi->drive;
-
-	drive->usage++;
-
 	return 0;
 }
 
@@ -817,9 +812,6 @@
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
 	struct ide_scsi_obj *scsi = ide_scsi_g(disk);
-	ide_drive_t *drive = scsi->drive;
-
-	drive->usage--;
 
 	ide_scsi_put(scsi);
 
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index afca45c..9d014e5 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -518,6 +518,10 @@
 	struct lpfc_sli *psli = &phba->sli;
 	struct lpfc_sli_ring  *pring;
 	uint32_t event_data;
+	/* If the pci channel is offline, ignore possible errors,
+	 * since we cannot communicate with the pci card anyway. */
+	if (pci_channel_offline(phba->pcidev))
+		return;
 
 	if (phba->work_hs & HS_FFER6 ||
 	    phba->work_hs & HS_FFER5) {
@@ -1797,6 +1801,92 @@
 	pci_set_drvdata(pdev, NULL);
 }
 
+/**
+ * lpfc_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci conneection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev,
+				pci_channel_state_t state)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata;
+	struct lpfc_sli *psli = &phba->sli;
+	struct lpfc_sli_ring  *pring;
+
+	if (state == pci_channel_io_perm_failure) {
+		lpfc_pci_remove_one(pdev);
+		return PCI_ERS_RESULT_DISCONNECT;
+	}
+	pci_disable_device(pdev);
+	/*
+	 * There may be I/Os dropped by the firmware.
+	 * Error iocb (I/O) on txcmplq and let the SCSI layer
+	 * retry it after re-establishing link.
+	 */
+	pring = &psli->ring[psli->fcp_ring];
+	lpfc_sli_abort_iocb_ring(phba, pring);
+
+	/* Request a slot reset. */
+	return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * lpfc_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot.
+ */
+static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata;
+	struct lpfc_sli *psli = &phba->sli;
+	int bars = pci_select_bars(pdev, IORESOURCE_MEM);
+
+	dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n");
+	if (pci_enable_device_bars(pdev, bars)) {
+		printk(KERN_ERR "lpfc: Cannot re-enable "
+			"PCI device after reset.\n");
+		return PCI_ERS_RESULT_DISCONNECT;
+	}
+
+	pci_set_master(pdev);
+
+	/* Re-establishing Link */
+	spin_lock_irq(phba->host->host_lock);
+	phba->fc_flag |= FC_ESTABLISH_LINK;
+	psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
+	spin_unlock_irq(phba->host->host_lock);
+
+
+	/* Take device offline; this will perform cleanup */
+	lpfc_offline(phba);
+	lpfc_sli_brdrestart(phba);
+
+	return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * lpfc_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells us that
+ * its OK to resume normal operation.
+ */
+static void lpfc_io_resume(struct pci_dev *pdev)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata;
+
+	if (lpfc_online(phba) == 0) {
+		mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60);
+	}
+}
+
 static struct pci_device_id lpfc_id_table[] = {
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_VIPER,
 		PCI_ANY_ID, PCI_ANY_ID, },
@@ -1857,11 +1947,18 @@
 
 MODULE_DEVICE_TABLE(pci, lpfc_id_table);
 
+static struct pci_error_handlers lpfc_err_handler = {
+	.error_detected = lpfc_io_error_detected,
+	.slot_reset = lpfc_io_slot_reset,
+	.resume = lpfc_io_resume,
+};
+
 static struct pci_driver lpfc_driver = {
 	.name		= LPFC_DRIVER_NAME,
 	.id_table	= lpfc_id_table,
 	.probe		= lpfc_pci_probe_one,
 	.remove		= __devexit_p(lpfc_pci_remove_one),
+	.err_handler = &lpfc_err_handler,
 };
 
 static int __init
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index a4128e1..9fb6960 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -2104,6 +2104,10 @@
 	volatile uint32_t word0, ldata;
 	void __iomem *to_slim;
 
+	/* If the PCI channel is in offline state, do not post mbox. */
+	if (unlikely(pci_channel_offline(phba->pcidev)))
+		return MBX_NOT_FINISHED;
+
 	psli = &phba->sli;
 
 	spin_lock_irqsave(phba->host->host_lock, drvr_flag);
@@ -2407,6 +2411,10 @@
 	struct lpfc_iocbq *nextiocb;
 	IOCB_t *iocb;
 
+	/* If the PCI channel is in offline state, do not post iocbs. */
+	if (unlikely(pci_channel_offline(phba->pcidev)))
+		return IOCB_ERROR;
+
 	/*
 	 * We should never get an IOCB if we are in a < LINK_DOWN state
 	 */
@@ -3154,6 +3162,10 @@
 	if (unlikely(!phba))
 		return IRQ_NONE;
 
+	/* If the pci channel is offline, ignore all the interrupts. */
+	if (unlikely(pci_channel_offline(phba->pcidev)))
+		return IRQ_NONE;
+
 	phba->sli.slistat.sli_intr++;
 
 	/*
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 808a1b8..0aa3304 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -5072,7 +5072,7 @@
 				"megaraid: failed to create megaraid root\n");
 	}
 #endif
-	error = pci_module_init(&megaraid_pci_driver);
+	error = pci_register_driver(&megaraid_pci_driver);
 	if (error) {
 #ifdef CONFIG_PROC_FS
 		remove_proc_entry("megaraid", &proc_root);
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 15e24fc..7a81267 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -10,11 +10,13 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_sas.c
- * Version	: v00.00.03.05
+ * Version	: v00.00.03.10-rc1
  *
  * Authors:
- * 	Sreenivas Bagalkote	<Sreenivas.Bagalkote@lsi.com>
- * 	Sumant Patro		<Sumant.Patro@lsi.com>
+ *	(email-id : megaraidlinux@lsi.com)
+ * 	Sreenivas Bagalkote
+ * 	Sumant Patro
+ *	Bo Yang
  *
  * List of supported controllers
  *
@@ -35,6 +37,7 @@
 #include <asm/uaccess.h>
 #include <linux/fs.h>
 #include <linux/compat.h>
+#include <linux/blkdev.h>
 #include <linux/mutex.h>
 
 #include <scsi/scsi.h>
@@ -841,6 +844,11 @@
 
 	instance = (struct megasas_instance *)
 	    scmd->device->host->hostdata;
+
+	/* Don't process if we have already declared adapter dead */
+	if (instance->hw_crit_error)
+		return SCSI_MLQUEUE_HOST_BUSY;
+
 	scmd->scsi_done = done;
 	scmd->result = 0;
 
@@ -850,6 +858,18 @@
 		goto out_done;
 	}
 
+	switch (scmd->cmnd[0]) {
+	case SYNCHRONIZE_CACHE:
+		/*
+		 * FW takes care of flush cache on its own
+		 * No need to send it down
+		 */
+		scmd->result = DID_OK << 16;
+		goto out_done;
+	default:
+		break;
+	}
+
 	cmd = megasas_get_cmd(instance);
 	if (!cmd)
 		return SCSI_MLQUEUE_HOST_BUSY;
@@ -1010,6 +1030,49 @@
 }
 
 /**
+ * megasas_bios_param - Returns disk geometry for a disk
+ * @sdev: 		device handle
+ * @bdev:		block device
+ * @capacity:		drive capacity
+ * @geom:		geometry parameters
+ */
+static int
+megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
+		 sector_t capacity, int geom[])
+{
+	int heads;
+	int sectors;
+	sector_t cylinders;
+	unsigned long tmp;
+	/* Default heads (64) & sectors (32) */
+	heads = 64;
+	sectors = 32;
+
+	tmp = heads * sectors;
+	cylinders = capacity;
+
+	sector_div(cylinders, tmp);
+
+	/*
+	 * Handle extended translation size for logical drives > 1Gb
+	 */
+
+	if (capacity >= 0x200000) {
+		heads = 255;
+		sectors = 63;
+		tmp = heads*sectors;
+		cylinders = capacity;
+		sector_div(cylinders, tmp);
+	}
+
+	geom[0] = heads;
+	geom[1] = sectors;
+	geom[2] = cylinders;
+
+	return 0;
+}
+
+/**
  * megasas_service_aen -	Processes an event notification
  * @instance:			Adapter soft state
  * @cmd:			AEN command completed by the ISR
@@ -1049,6 +1112,7 @@
 	.eh_device_reset_handler = megasas_reset_device,
 	.eh_bus_reset_handler = megasas_reset_bus_host,
 	.eh_host_reset_handler = megasas_reset_bus_host,
+	.bios_param = megasas_bios_param,
 	.use_clustering = ENABLE_CLUSTERING,
 };
 
@@ -1282,11 +1346,13 @@
 	if(instance->instancet->clear_intr(instance->reg_set))
 		return IRQ_NONE;
 
+	if (instance->hw_crit_error)
+		goto out_done;
         /*
 	 * Schedule the tasklet for cmd completion
 	 */
 	tasklet_schedule(&instance->isr_tasklet);
-
+out_done:
 	return IRQ_HANDLED;
 }
 
@@ -1741,6 +1807,10 @@
 	struct megasas_cmd *cmd;
 	struct megasas_instance *instance = (struct megasas_instance *)instance_addr;
 
+	/* If we have already declared adapter dead, donot complete cmds */
+	if (instance->hw_crit_error)
+		return;
+
 	producer = *instance->producer;
 	consumer = *instance->consumer;
 
@@ -2655,9 +2725,9 @@
 	 * For each user buffer, create a mirror buffer and copy in
 	 */
 	for (i = 0; i < ioc->sge_count; i++) {
-		kbuff_arr[i] = pci_alloc_consistent(instance->pdev,
+		kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev,
 						    ioc->sgl[i].iov_len,
-						    &buf_handle);
+						    &buf_handle, GFP_KERNEL);
 		if (!kbuff_arr[i]) {
 			printk(KERN_DEBUG "megasas: Failed to alloc "
 			       "kernel SGL buffer for IOCTL \n");
@@ -2684,8 +2754,8 @@
 	}
 
 	if (ioc->sense_len) {
-		sense = pci_alloc_consistent(instance->pdev, ioc->sense_len,
-					     &sense_handle);
+		sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len,
+					     &sense_handle, GFP_KERNEL);
 		if (!sense) {
 			error = -ENOMEM;
 			goto out;
@@ -2744,12 +2814,12 @@
 
       out:
 	if (sense) {
-		pci_free_consistent(instance->pdev, ioc->sense_len,
+		dma_free_coherent(&instance->pdev->dev, ioc->sense_len,
 				    sense, sense_handle);
 	}
 
 	for (i = 0; i < ioc->sge_count && kbuff_arr[i]; i++) {
-		pci_free_consistent(instance->pdev,
+		dma_free_coherent(&instance->pdev->dev,
 				    kern_sge32[i].length,
 				    kbuff_arr[i], kern_sge32[i].phys_addr);
 	}
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index cacb3ad..e862992 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -18,9 +18,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION				"00.00.03.05"
-#define MEGASAS_RELDATE				"Oct 02, 2006"
-#define MEGASAS_EXT_VERSION			"Mon Oct 02 11:21:32 PDT 2006"
+#define MEGASAS_VERSION				"00.00.03.10-rc1"
+#define MEGASAS_RELDATE				"Feb 14, 2007"
+#define MEGASAS_EXT_VERSION			"Wed Feb 14 10:14:25 PST 2007"
 
 /*
  * Device IDs
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 9668b73..a967fad 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -5574,14 +5574,14 @@
 
 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
 
-static int osst_create_driverfs_files(struct device_driver *driverfs)
+static int osst_create_sysfs_files(struct device_driver *sysfs)
 {
-	return driver_create_file(driverfs, &driver_attr_version);
+	return driver_create_file(sysfs, &driver_attr_version);
 }
 
-static void osst_remove_driverfs_files(struct device_driver *driverfs)
+static void osst_remove_sysfs_files(struct device_driver *sysfs)
 {
-	driver_remove_file(driverfs, &driver_attr_version);
+	driver_remove_file(sysfs, &driver_attr_version);
 }
 
 /*
@@ -5953,7 +5953,7 @@
 	if (err)
 		goto err_out_chrdev;
 
-	err = osst_create_driverfs_files(&osst_template.gendrv);
+	err = osst_create_sysfs_files(&osst_template.gendrv);
 	if (err)
 		goto err_out_scsidrv;
 
@@ -5973,7 +5973,7 @@
 	int i;
 	struct osst_tape * STp;
 
-	osst_remove_driverfs_files(&osst_template.gendrv);
+	osst_remove_sysfs_files(&osst_template.gendrv);
 	scsi_unregister_driver(&osst_template.gendrv);
 	unregister_chrdev(OSST_MAJOR, "osst");
 	osst_sysfs_cleanup();
diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
index 69d6e9b..bb6f051 100644
--- a/drivers/scsi/scsi_proc.c
+++ b/drivers/scsi/scsi_proc.c
@@ -179,9 +179,8 @@
 	seq_printf(s, "\n");
 
 	seq_printf(s, "  Type:   %s ", scsi_device_type(sdev->type));
-	seq_printf(s, "               ANSI"
-		     " SCSI revision: %02x", (sdev->scsi_level - 1) ?
-		     sdev->scsi_level - 1 : 1);
+	seq_printf(s, "               ANSI  SCSI revision: %02x",
+			sdev->scsi_level - (sdev->scsi_level > 1));
 	if (sdev->scsi_level == 2)
 		seq_printf(s, " CCS\n");
 	else
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index a43b9ec..0949145 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -54,7 +54,7 @@
 #define SCSI_TIMEOUT (2*HZ)
 
 /*
- * Prefix values for the SCSI id's (stored in driverfs name field)
+ * Prefix values for the SCSI id's (stored in sysfs name field)
  */
 #define SCSI_UID_SER_NUM 'S'
 #define SCSI_UID_UNKNOWN 'Z'
@@ -385,6 +385,7 @@
 	INIT_LIST_HEAD(&starget->siblings);
 	INIT_LIST_HEAD(&starget->devices);
 	starget->state = STARGET_RUNNING;
+	starget->scsi_level = SCSI_2;
  retry:
 	spin_lock_irqsave(shost->host_lock, flags);
 
@@ -654,6 +655,19 @@
 	 * short INQUIRY), an abort here prevents any further use of the
 	 * device, including spin up.
 	 *
+	 * On the whole, the best approach seems to be to assume the first
+	 * 36 bytes are valid no matter what the device says.  That's
+	 * better than copying < 36 bytes to the inquiry-result buffer
+	 * and displaying garbage for the Vendor, Product, or Revision
+	 * strings.
+	 */
+	if (sdev->inquiry_len < 36) {
+		printk(KERN_INFO "scsi scan: INQUIRY result too short (%d),"
+				" using 36\n", sdev->inquiry_len);
+		sdev->inquiry_len = 36;
+	}
+
+	/*
 	 * Related to the above issue:
 	 *
 	 * XXX Devices (disk or all?) should be sent a TEST UNIT READY,
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 259c90c..c275dca 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -922,7 +922,7 @@
 	snprintf(sdev->sdev_classdev.class_id, BUS_ID_SIZE,
 		 "%d:%d:%d:%d", sdev->host->host_no,
 		 sdev->channel, sdev->id, sdev->lun);
-	sdev->scsi_level = SCSI_2;
+	sdev->scsi_level = starget->scsi_level;
 	transport_setup_device(&sdev->sdev_gendev);
 	spin_lock_irqsave(shost->host_lock, flags);
 	list_add_tail(&sdev->same_target_siblings, &starget->devices);
diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c
index f2344ab..0e08817 100644
--- a/drivers/scsi/scsi_tgt_if.c
+++ b/drivers/scsi/scsi_tgt_if.c
@@ -33,6 +33,14 @@
 
 #include "scsi_tgt_priv.h"
 
+#if TGT_RING_SIZE < PAGE_SIZE
+#  define TGT_RING_SIZE PAGE_SIZE
+#endif
+
+#define TGT_RING_PAGES (TGT_RING_SIZE >> PAGE_SHIFT)
+#define TGT_EVENT_PER_PAGE (PAGE_SIZE / sizeof(struct tgt_event))
+#define TGT_MAX_EVENTS (TGT_EVENT_PER_PAGE * TGT_RING_PAGES)
+
 struct tgt_ring {
 	u32 tr_idx;
 	unsigned long tr_pages[TGT_RING_PAGES];
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 0d3c10f..58afdb4 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -855,7 +855,7 @@
 
 /*
  * Note: in the target show function we recognize when the remote
- *  port is in the heirarchy and do not allow the driver to get
+ *  port is in the hierarchy and do not allow the driver to get
  *  involved in sysfs functions. The driver only gets involved if
  *  it's the "old" style that doesn't use rports.
  */
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index 6d39150e..b2ef71a 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -500,7 +500,7 @@
 EXPORT_SYMBOL(sas_phy_alloc);
 
 /**
- * sas_phy_add  --  add a SAS PHY to the device hierachy
+ * sas_phy_add  --  add a SAS PHY to the device hierarchy
  * @phy:	The PHY to be added
  *
  * Publishes a SAS PHY to the rest of the system.
@@ -1265,7 +1265,7 @@
 EXPORT_SYMBOL(sas_expander_alloc);
 
 /**
- * sas_rphy_add  --  add a SAS remote PHY to the device hierachy
+ * sas_rphy_add  --  add a SAS remote PHY to the device hierarchy
  * @rphy:	The remote PHY to be added
  *
  * Publishes a SAS remote PHY to the rest of the system.
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 3f048bd..5a8f55f 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1269,9 +1269,18 @@
 
 	/* Some devices return the total number of sectors, not the
 	 * highest sector number.  Make the necessary adjustment. */
-	if (sdp->fix_capacity)
+	if (sdp->fix_capacity) {
 		--sdkp->capacity;
 
+	/* Some devices have version which report the correct sizes
+	 * and others which do not. We guess size according to a heuristic
+	 * and err on the side of lowering the capacity. */
+	} else {
+		if (sdp->guess_capacity)
+			if (sdkp->capacity & 0x01) /* odd sizes are odd */
+				--sdkp->capacity;
+	}
+
 got_data:
 	if (sector_size == 0) {
 		sector_size = 512;
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c
index e81f97a..a15752b 100644
--- a/drivers/scsi/sgiwd93.c
+++ b/drivers/scsi/sgiwd93.c
@@ -244,9 +244,10 @@
 	regs.SASR = wdregs + 3;
 	regs.SCMD = wdregs + 7;
 
-	wd33c93_init(host, regs, dma_setup, dma_stop, WD33C93_FS_16_20);
+	wd33c93_init(host, regs, dma_setup, dma_stop, WD33C93_FS_MHZ(20));
 
-	hdata->wh.no_sync = 0;
+	if (hdata->wh.no_sync == 0xff)
+		hdata->wh.no_sync = 0;
 
 	if (request_irq(irq, sgiwd93_intr, 0, "SGI WD93", (void *) host)) {
 		printk(KERN_WARNING "sgiwd93: Could not register irq %d "
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 3d2e023..98d8411 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -195,8 +195,8 @@
 static int st_probe(struct device *);
 static int st_remove(struct device *);
 
-static int do_create_driverfs_files(void);
-static void do_remove_driverfs_files(void);
+static int do_create_sysfs_files(void);
+static void do_remove_sysfs_files(void);
 static int do_create_class_files(struct scsi_tape *, int, int);
 
 static struct scsi_driver st_template = {
@@ -4193,7 +4193,7 @@
 	if (err)
 		goto err_chrdev;
 
-	err = do_create_driverfs_files();
+	err = do_create_sysfs_files();
 	if (err)
 		goto err_scsidrv;
 
@@ -4211,7 +4211,7 @@
 
 static void __exit exit_st(void)
 {
-	do_remove_driverfs_files();
+	do_remove_sysfs_files();
 	scsi_unregister_driver(&st_template.gendrv);
 	unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
 				 ST_MAX_TAPE_ENTRIES);
@@ -4249,43 +4249,43 @@
 }
 static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
 
-static int do_create_driverfs_files(void)
+static int do_create_sysfs_files(void)
 {
-	struct device_driver *driverfs = &st_template.gendrv;
+	struct device_driver *sysfs = &st_template.gendrv;
 	int err;
 
-	err = driver_create_file(driverfs, &driver_attr_try_direct_io);
+	err = driver_create_file(sysfs, &driver_attr_try_direct_io);
 	if (err)
 		return err;
-	err = driver_create_file(driverfs, &driver_attr_fixed_buffer_size);
+	err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
 	if (err)
 		goto err_try_direct_io;
-	err = driver_create_file(driverfs, &driver_attr_max_sg_segs);
+	err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
 	if (err)
 		goto err_attr_fixed_buf;
-	err = driver_create_file(driverfs, &driver_attr_version);
+	err = driver_create_file(sysfs, &driver_attr_version);
 	if (err)
 		goto err_attr_max_sg;
 
 	return 0;
 
 err_attr_max_sg:
-	driver_remove_file(driverfs, &driver_attr_max_sg_segs);
+	driver_remove_file(sysfs, &driver_attr_max_sg_segs);
 err_attr_fixed_buf:
-	driver_remove_file(driverfs, &driver_attr_fixed_buffer_size);
+	driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
 err_try_direct_io:
-	driver_remove_file(driverfs, &driver_attr_try_direct_io);
+	driver_remove_file(sysfs, &driver_attr_try_direct_io);
 	return err;
 }
 
-static void do_remove_driverfs_files(void)
+static void do_remove_sysfs_files(void)
 {
-	struct device_driver *driverfs = &st_template.gendrv;
+	struct device_driver *sysfs = &st_template.gendrv;
 
-	driver_remove_file(driverfs, &driver_attr_version);
-	driver_remove_file(driverfs, &driver_attr_max_sg_segs);
-	driver_remove_file(driverfs, &driver_attr_fixed_buffer_size);
-	driver_remove_file(driverfs, &driver_attr_try_direct_io);
+	driver_remove_file(sysfs, &driver_attr_version);
+	driver_remove_file(sysfs, &driver_attr_max_sg_segs);
+	driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
+	driver_remove_file(sysfs, &driver_attr_try_direct_io);
 }
 
 
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw1.h b/drivers/scsi/sym53c8xx_2/sym_fw1.h
index 7b39f4a..7b08d6c 100644
--- a/drivers/scsi/sym53c8xx_2/sym_fw1.h
+++ b/drivers/scsi/sym53c8xx_2/sym_fw1.h
@@ -1020,7 +1020,7 @@
 	 *  It shall be a tagged command.
 	 *  Read SIMPLE+TAG.
 	 *  The C code will deal with errors.
-	 *  Agressive optimization, is'nt it? :)
+	 *  Aggressive optimization, isn't it? :)
 	 */
 	SCR_MOVE_ABS (2) ^ SCR_MSG_IN,
 		HADDR_1 (msgin),
@@ -1044,7 +1044,7 @@
 		RADDR_1 (dsa),
 	/*
 	 *  The SIDL still contains the TAG value.
-	 *  Agressive optimization, isn't it? :):)
+	 *  Aggressive optimization, isn't it? :):)
 	 */
 	SCR_REG_SFBR (sidl, SCR_SHL, 0),
 		0,
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw2.h b/drivers/scsi/sym53c8xx_2/sym_fw2.h
index 851f270..6e5b952 100644
--- a/drivers/scsi/sym53c8xx_2/sym_fw2.h
+++ b/drivers/scsi/sym53c8xx_2/sym_fw2.h
@@ -956,7 +956,7 @@
 	 *  It shall be a tagged command.
 	 *  Read SIMPLE+TAG.
 	 *  The C code will deal with errors.
-	 *  Agressive optimization, is'nt it? :)
+	 *  Aggressive optimization, isn't it? :)
 	 */
 	SCR_MOVE_ABS (2) ^ SCR_MSG_IN,
 		HADDR_1 (msgin),
@@ -968,7 +968,7 @@
 		offsetof(struct sym_lcb, head.itlq_tbl_sa),
 	/*
 	 *  The SIDL still contains the TAG value.
-	 *  Agressive optimization, isn't it? :):)
+	 *  Aggressive optimization, isn't it? :):)
 	 */
 	SCR_REG_SFBR (sidl, SCR_SHL, 0),
 		0,
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index 8357516..fa4e08e 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -69,6 +69,11 @@
  * Added support for pre -A chips, which don't have advanced features
  * and will generate CSR_RESEL rather than CSR_RESEL_AM.
  *	Richard Hirst <richard@sleepie.demon.co.uk>  August 2000
+ *
+ * Added support for Burst Mode DMA and Fast SCSI. Enabled the use of
+ * default_sx_per for asynchronous data transfers. Added adjustment
+ * of transfer periods in sx_table to the actual input-clock.
+ *  peter fuerst <post@pfrst.de>  February 2007
  */
 
 #include <linux/module.h>
@@ -86,9 +91,11 @@
 
 #include "wd33c93.h"
 
+#define optimum_sx_per(hostdata) (hostdata)->sx_table[1].period_ns
 
-#define WD33C93_VERSION    "1.26"
-#define WD33C93_DATE       "22/Feb/2003"
+
+#define WD33C93_VERSION    "1.26++"
+#define WD33C93_DATE       "10/Feb/2007"
 
 MODULE_AUTHOR("John Shifflett");
 MODULE_DESCRIPTION("Generic WD33C93 SCSI driver");
@@ -122,6 +129,13 @@
  *                    defines in wd33c93.h
  * -  clock:x        -x = clock input in MHz for WD33c93 chip. Normal values
  *                    would be from 8 through 20. Default is 8.
+ * -  burst:x        -x = 1 to use Burst Mode (or Demand-Mode) DMA, x = 0 to use
+ *                    Single Byte DMA, which is the default. Argument is
+ *                    optional - if not present, same as "burst:1".
+ * -  fast:x         -x = 1 to enable Fast SCSI, which is only effective with
+ *                    input-clock divisor 4 (WD33C93_FS_16_20), x = 0 to disable
+ *                    it, which is the default.  Argument is optional - if not
+ *                    present, same as "fast:1".
  * -  next           -No argument. Used to separate blocks of keywords when
  *                    there's more than one host adapter in the system.
  *
@@ -148,7 +162,7 @@
  */
 
 /* Normally, no defaults are specified */
-static char *setup_args[] = { "", "", "", "", "", "", "", "", "" };
+static char *setup_args[] = { "", "", "", "", "", "", "", "", "", "" };
 
 static char *setup_strings;
 module_param(setup_strings, charp, 0);
@@ -298,20 +312,8 @@
 	return x;
 }
 
-static struct sx_period sx_table[] = {
-	{1, 0x20},
-	{252, 0x20},
-	{376, 0x30},
-	{500, 0x40},
-	{624, 0x50},
-	{752, 0x60},
-	{876, 0x70},
-	{1000, 0x00},
-	{0, 0}
-};
-
 static int
-round_period(unsigned int period)
+round_period(unsigned int period, const struct sx_period *sx_table)
 {
 	int x;
 
@@ -324,17 +326,49 @@
 	return 7;
 }
 
+/*
+ * Calculate Synchronous Transfer Register value from SDTR code.
+ */
 static uchar
-calc_sync_xfer(unsigned int period, unsigned int offset)
+calc_sync_xfer(unsigned int period, unsigned int offset, unsigned int fast,
+               const struct sx_period *sx_table)
 {
+	/* When doing Fast SCSI synchronous data transfers, the corresponding
+	 * value in 'sx_table' is two times the actually used transfer period.
+	 */
 	uchar result;
 
+	if (offset && fast) {
+		fast = STR_FSS;
+		period *= 2;
+	} else {
+		fast = 0;
+	}
 	period *= 4;		/* convert SDTR code to ns */
-	result = sx_table[round_period(period)].reg_value;
+	result = sx_table[round_period(period,sx_table)].reg_value;
 	result |= (offset < OPTIMUM_SX_OFF) ? offset : OPTIMUM_SX_OFF;
+	result |= fast;
 	return result;
 }
 
+/*
+ * Calculate SDTR code bytes [3],[4] from period and offset.
+ */
+static inline void
+calc_sync_msg(unsigned int period, unsigned int offset, unsigned int fast,
+                uchar  msg[2])
+{
+	/* 'period' is a "normal"-mode value, like the ones in 'sx_table'. The
+	 * actually used transfer period for Fast SCSI synchronous data
+	 * transfers is half that value.
+	 */
+	period /= 4;
+	if (offset && fast)
+		period /= 2;
+	msg[0] = period;
+	msg[1] = offset;
+}
+
 int
 wd33c93_queuecommand(struct scsi_cmnd *cmd,
 		void (*done)(struct scsi_cmnd *))
@@ -632,7 +666,7 @@
 				write_wd33c93_count(regs,
 						    cmd->SCp.this_residual);
 				write_wd33c93(regs, WD_CONTROL,
-					      CTRL_IDI | CTRL_EDI | CTRL_DMA);
+					      CTRL_IDI | CTRL_EDI | hostdata->dma_mode);
 				hostdata->dma = D_DMA_RUNNING;
 			}
 		} else
@@ -712,6 +746,8 @@
 		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
 		    cmd->SCp.buffer->offset;
 	}
+	if (!cmd->SCp.this_residual) /* avoid bogus setups */
+		return;
 
 	write_wd33c93(regs, WD_SYNCHRONOUS_TRANSFER,
 		      hostdata->sync_xfer[cmd->device->id]);
@@ -744,7 +780,7 @@
 #ifdef PROC_STATISTICS
 		hostdata->dma_cnt++;
 #endif
-		write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_DMA);
+		write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | hostdata->dma_mode);
 		write_wd33c93_count(regs, cmd->SCp.this_residual);
 
 		if ((hostdata->level2 >= L2_DATA) ||
@@ -862,9 +898,6 @@
 			hostdata->outgoing_msg[0] |= 0x40;
 
 		if (hostdata->sync_stat[cmd->device->id] == SS_FIRST) {
-#ifdef SYNC_DEBUG
-			printk(" sending SDTR ");
-#endif
 
 			hostdata->sync_stat[cmd->device->id] = SS_WAITING;
 
@@ -878,14 +911,20 @@
 			hostdata->outgoing_msg[2] = 3;
 			hostdata->outgoing_msg[3] = EXTENDED_SDTR;
 			if (hostdata->no_sync & (1 << cmd->device->id)) {
-				hostdata->outgoing_msg[4] =
-				    hostdata->default_sx_per / 4;
-				hostdata->outgoing_msg[5] = 0;
+				calc_sync_msg(hostdata->default_sx_per, 0,
+						0, hostdata->outgoing_msg + 4);
 			} else {
-				hostdata->outgoing_msg[4] = OPTIMUM_SX_PER / 4;
-				hostdata->outgoing_msg[5] = OPTIMUM_SX_OFF;
+				calc_sync_msg(optimum_sx_per(hostdata),
+						OPTIMUM_SX_OFF,
+						hostdata->fast,
+						hostdata->outgoing_msg + 4);
 			}
 			hostdata->outgoing_len = 6;
+#ifdef SYNC_DEBUG
+			ucp = hostdata->outgoing_msg + 1;
+			printk(" sending SDTR %02x03%02x%02x%02x ",
+				ucp[0], ucp[2], ucp[3], ucp[4]);
+#endif
 		} else
 			hostdata->outgoing_len = 1;
 
@@ -1001,8 +1040,13 @@
 #ifdef SYNC_DEBUG
 			    printk("-REJ-");
 #endif
-			if (hostdata->sync_stat[cmd->device->id] == SS_WAITING)
+			if (hostdata->sync_stat[cmd->device->id] == SS_WAITING) {
 				hostdata->sync_stat[cmd->device->id] = SS_SET;
+				/* we want default_sx_per, not DEFAULT_SX_PER */
+				hostdata->sync_xfer[cmd->device->id] =
+					calc_sync_xfer(hostdata->default_sx_per
+						/ 4, 0, 0, hostdata->sx_table);
+			}
 			write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
 			hostdata->state = S_CONNECTED;
 			break;
@@ -1022,7 +1066,10 @@
 
 				switch (ucp[2]) {	/* what's the EXTENDED code? */
 				case EXTENDED_SDTR:
-					id = calc_sync_xfer(ucp[3], ucp[4]);
+					/* default to default async period */
+					id = calc_sync_xfer(hostdata->
+							default_sx_per / 4, 0,
+							0, hostdata->sx_table);
 					if (hostdata->sync_stat[cmd->device->id] !=
 					    SS_WAITING) {
 
@@ -1041,20 +1088,22 @@
 						hostdata->outgoing_msg[1] = 3;
 						hostdata->outgoing_msg[2] =
 						    EXTENDED_SDTR;
-						hostdata->outgoing_msg[3] =
-						    hostdata->default_sx_per /
-						    4;
-						hostdata->outgoing_msg[4] = 0;
+						calc_sync_msg(hostdata->
+							default_sx_per, 0,
+							0, hostdata->outgoing_msg + 3);
 						hostdata->outgoing_len = 5;
-						hostdata->sync_xfer[cmd->device->id] =
-						    calc_sync_xfer(hostdata->
-								   default_sx_per
-								   / 4, 0);
 					} else {
-						hostdata->sync_xfer[cmd->device->id] = id;
+						if (ucp[4]) /* well, sync transfer */
+							id = calc_sync_xfer(ucp[3], ucp[4],
+									hostdata->fast,
+									hostdata->sx_table);
+						else if (ucp[3]) /* very unlikely... */
+							id = calc_sync_xfer(ucp[3], ucp[4],
+									0, hostdata->sx_table);
 					}
+					hostdata->sync_xfer[cmd->device->id] = id;
 #ifdef SYNC_DEBUG
-					printk("sync_xfer=%02x",
+					printk(" sync_xfer=%02x\n",
 					       hostdata->sync_xfer[cmd->device->id]);
 #endif
 					hostdata->sync_stat[cmd->device->id] =
@@ -1486,7 +1535,7 @@
 	write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
 	write_wd33c93(regs, WD_SYNCHRONOUS_TRANSFER,
 		      calc_sync_xfer(hostdata->default_sx_per / 4,
-				     DEFAULT_SX_OFF));
+				     DEFAULT_SX_OFF, 0, hostdata->sx_table));
 	write_wd33c93(regs, WD_COMMAND, WD_CMD_RESET);
 
 
@@ -1512,6 +1561,9 @@
 	} else
 		hostdata->chip = C_UNKNOWN_CHIP;
 
+	if (hostdata->chip != C_WD33C93B)	/* Fast SCSI unavailable */
+		hostdata->fast = 0;
+
 	write_wd33c93(regs, WD_TIMEOUT_PERIOD, TIMEOUT_PERIOD_VALUE);
 	write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
 }
@@ -1533,7 +1585,8 @@
 	for (i = 0; i < 8; i++) {
 		hostdata->busy[i] = 0;
 		hostdata->sync_xfer[i] =
-		    calc_sync_xfer(DEFAULT_SX_PER / 4, DEFAULT_SX_OFF);
+			calc_sync_xfer(DEFAULT_SX_PER / 4, DEFAULT_SX_OFF,
+					0, hostdata->sx_table);
 		hostdata->sync_stat[i] = SS_UNSET;	/* using default sync values */
 	}
 	hostdata->input_Q = NULL;
@@ -1782,6 +1835,98 @@
 	return ++x;
 }
 
+/*
+ * Calculate internal data-transfer-clock cycle from input-clock
+ * frequency (/MHz) and fill 'sx_table'.
+ *
+ * The original driver used to rely on a fixed sx_table, containing periods
+ * for (only) the lower limits of the respective input-clock-frequency ranges
+ * (8-10/12-15/16-20 MHz). Although it seems, that no problems ocurred with
+ * this setting so far, it might be desirable to adjust the transfer periods
+ * closer to the really attached, possibly 25% higher, input-clock, since
+ * - the wd33c93 may really use a significant shorter period, than it has
+ *   negotiated (eg. thrashing the target, which expects 4/8MHz, with 5/10MHz
+ *   instead).
+ * - the wd33c93 may ask the target for a lower transfer rate, than the target
+ *   is capable of (eg. negotiating for an assumed minimum of 252ns instead of
+ *   possible 200ns, which indeed shows up in tests as an approx. 10% lower
+ *   transfer rate).
+ */
+static inline unsigned int
+round_4(unsigned int x)
+{
+	switch (x & 3) {
+		case 1: --x;
+			break;
+		case 2: ++x;
+		case 3: ++x;
+	}
+	return x;
+}
+
+static void
+calc_sx_table(unsigned int mhz, struct sx_period sx_table[9])
+{
+	unsigned int d, i;
+	if (mhz < 11)
+		d = 2;	/* divisor for  8-10 MHz input-clock */
+	else if (mhz < 16)
+		d = 3;	/* divisor for 12-15 MHz input-clock */
+	else
+		d = 4;	/* divisor for 16-20 MHz input-clock */
+
+	d = (100000 * d) / 2 / mhz; /* 100 x DTCC / nanosec */
+
+	sx_table[0].period_ns = 1;
+	sx_table[0].reg_value = 0x20;
+	for (i = 1; i < 8; i++) {
+		sx_table[i].period_ns = round_4((i+1)*d / 100);
+		sx_table[i].reg_value = (i+1)*0x10;
+	}
+	sx_table[7].reg_value = 0;
+	sx_table[8].period_ns = 0;
+	sx_table[8].reg_value = 0;
+}
+
+/*
+ * check and, maybe, map an init- or "clock:"- argument.
+ */
+static uchar
+set_clk_freq(int freq, int *mhz)
+{
+	int x = freq;
+	if (WD33C93_FS_8_10 == freq)
+		freq = 8;
+	else if (WD33C93_FS_12_15 == freq)
+		freq = 12;
+	else if (WD33C93_FS_16_20 == freq)
+		freq = 16;
+	else if (freq > 7 && freq < 11)
+		x = WD33C93_FS_8_10;
+		else if (freq > 11 && freq < 16)
+		x = WD33C93_FS_12_15;
+		else if (freq > 15 && freq < 21)
+		x = WD33C93_FS_16_20;
+	else {
+			/* Hmm, wouldn't it be safer to assume highest freq here? */
+		x = WD33C93_FS_8_10;
+		freq = 8;
+	}
+	*mhz = freq;
+	return x;
+}
+
+/*
+ * to be used with the resync: fast: ... options
+ */
+static inline void set_resync ( struct WD33C93_hostdata *hd, int mask )
+{
+	int i;
+	for (i = 0; i < 8; i++)
+		if (mask & (1 << i))
+			hd->sync_stat[i] = SS_UNSET;
+}
+
 void
 wd33c93_init(struct Scsi_Host *instance, const wd33c93_regs regs,
 	     dma_setup_t setup, dma_stop_t stop, int clock_freq)
@@ -1798,7 +1943,8 @@
 	hostdata = (struct WD33C93_hostdata *) instance->hostdata;
 
 	hostdata->regs = regs;
-	hostdata->clock_freq = clock_freq;
+	hostdata->clock_freq = set_clk_freq(clock_freq, &i);
+	calc_sx_table(i, hostdata->sx_table);
 	hostdata->dma_setup = setup;
 	hostdata->dma_stop = stop;
 	hostdata->dma_bounce_buffer = NULL;
@@ -1806,7 +1952,8 @@
 	for (i = 0; i < 8; i++) {
 		hostdata->busy[i] = 0;
 		hostdata->sync_xfer[i] =
-		    calc_sync_xfer(DEFAULT_SX_PER / 4, DEFAULT_SX_OFF);
+			calc_sync_xfer(DEFAULT_SX_PER / 4, DEFAULT_SX_OFF,
+					0, hostdata->sx_table);
 		hostdata->sync_stat[i] = SS_UNSET;	/* using default sync values */
 #ifdef PROC_STATISTICS
 		hostdata->cmd_cnt[i] = 0;
@@ -1828,6 +1975,8 @@
 	hostdata->default_sx_per = DEFAULT_SX_PER;
 	hostdata->no_sync = 0xff;	/* sync defaults to off */
 	hostdata->no_dma = 0;	/* default is DMA enabled */
+	hostdata->fast = 0;	/* default is Fast SCSI transfers disabled */
+	hostdata->dma_mode = CTRL_DMA;	/* default is Single Byte DMA */
 
 #ifdef PROC_INTERFACE
 	hostdata->proc = PR_VERSION | PR_INFO | PR_STATISTICS |
@@ -1839,6 +1988,11 @@
 #endif
 #endif
 
+	if (check_setup_args("clock", &flags, &val, buf)) {
+		hostdata->clock_freq = set_clk_freq(val, &val);
+		calc_sx_table(val, hostdata->sx_table);
+	}
+
 	if (check_setup_args("nosync", &flags, &val, buf))
 		hostdata->no_sync = val;
 
@@ -1847,7 +2001,8 @@
 
 	if (check_setup_args("period", &flags, &val, buf))
 		hostdata->default_sx_per =
-		    sx_table[round_period((unsigned int) val)].period_ns;
+		    hostdata->sx_table[round_period((unsigned int) val,
+		                                    hostdata->sx_table)].period_ns;
 
 	if (check_setup_args("disconnect", &flags, &val, buf)) {
 		if ((val >= DIS_NEVER) && (val <= DIS_ALWAYS))
@@ -1862,17 +2017,12 @@
 	if (check_setup_args("debug", &flags, &val, buf))
 		hostdata->args = val & DB_MASK;
 
-	if (check_setup_args("clock", &flags, &val, buf)) {
-		if (val > 7 && val < 11)
-			val = WD33C93_FS_8_10;
-		else if (val > 11 && val < 16)
-			val = WD33C93_FS_12_15;
-		else if (val > 15 && val < 21)
-			val = WD33C93_FS_16_20;
-		else
-			val = WD33C93_FS_8_10;
-		hostdata->clock_freq = val;
-	}
+	if (check_setup_args("burst", &flags, &val, buf))
+		hostdata->dma_mode = val ? CTRL_BURST:CTRL_DMA;
+
+	if (WD33C93_FS_16_20 == hostdata->clock_freq /* divisor 4 */
+		&& check_setup_args("fast", &flags, &val, buf))
+		hostdata->fast = !!val;
 
 	if ((i = check_setup_args("next", &flags, &val, buf))) {
 		while (i)
@@ -1917,53 +2067,65 @@
 	char tbuf[128];
 	struct WD33C93_hostdata *hd;
 	struct scsi_cmnd *cmd;
-	int x, i;
+	int x;
 	static int stop = 0;
 
 	hd = (struct WD33C93_hostdata *) instance->hostdata;
 
 /* If 'in' is TRUE we need to _read_ the proc file. We accept the following
- * keywords (same format as command-line, but only ONE per read):
+ * keywords (same format as command-line, but arguments are not optional):
  *    debug
  *    disconnect
  *    period
  *    resync
  *    proc
  *    nodma
+ *    level2
+ *    burst
+ *    fast
+ *    nosync
  */
 
 	if (in) {
 		buf[len] = '\0';
-		bp = buf;
+		for (bp = buf; *bp; ) {
+			while (',' == *bp || ' ' == *bp)
+				++bp;
 		if (!strncmp(bp, "debug:", 6)) {
-			bp += 6;
-			hd->args = simple_strtoul(bp, NULL, 0) & DB_MASK;
+				hd->args = simple_strtoul(bp+6, &bp, 0) & DB_MASK;
 		} else if (!strncmp(bp, "disconnect:", 11)) {
-			bp += 11;
-			x = simple_strtoul(bp, NULL, 0);
+				x = simple_strtoul(bp+11, &bp, 0);
 			if (x < DIS_NEVER || x > DIS_ALWAYS)
 				x = DIS_ADAPTIVE;
 			hd->disconnect = x;
 		} else if (!strncmp(bp, "period:", 7)) {
-			bp += 7;
-			x = simple_strtoul(bp, NULL, 0);
+			x = simple_strtoul(bp+7, &bp, 0);
 			hd->default_sx_per =
-			    sx_table[round_period((unsigned int) x)].period_ns;
+				hd->sx_table[round_period((unsigned int) x,
+							  hd->sx_table)].period_ns;
 		} else if (!strncmp(bp, "resync:", 7)) {
-			bp += 7;
-			x = simple_strtoul(bp, NULL, 0);
-			for (i = 0; i < 7; i++)
-				if (x & (1 << i))
-					hd->sync_stat[i] = SS_UNSET;
+				set_resync(hd, (int)simple_strtoul(bp+7, &bp, 0));
 		} else if (!strncmp(bp, "proc:", 5)) {
-			bp += 5;
-			hd->proc = simple_strtoul(bp, NULL, 0);
+				hd->proc = simple_strtoul(bp+5, &bp, 0);
 		} else if (!strncmp(bp, "nodma:", 6)) {
-			bp += 6;
-			hd->no_dma = simple_strtoul(bp, NULL, 0);
+				hd->no_dma = simple_strtoul(bp+6, &bp, 0);
 		} else if (!strncmp(bp, "level2:", 7)) {
-			bp += 7;
-			hd->level2 = simple_strtoul(bp, NULL, 0);
+				hd->level2 = simple_strtoul(bp+7, &bp, 0);
+			} else if (!strncmp(bp, "burst:", 6)) {
+				hd->dma_mode =
+					simple_strtol(bp+6, &bp, 0) ? CTRL_BURST:CTRL_DMA;
+			} else if (!strncmp(bp, "fast:", 5)) {
+				x = !!simple_strtol(bp+5, &bp, 0);
+				if (x != hd->fast)
+					set_resync(hd, 0xff);
+				hd->fast = x;
+			} else if (!strncmp(bp, "nosync:", 7)) {
+				x = simple_strtoul(bp+7, &bp, 0);
+				set_resync(hd, x ^ hd->no_sync);
+				hd->no_sync = x;
+			} else {
+				break; /* unknown keyword,syntax-error,... */
+			}
 		}
 		return len;
 	}
@@ -1977,8 +2139,9 @@
 		strcat(bp, tbuf);
 	}
 	if (hd->proc & PR_INFO) {
-		sprintf(tbuf, "\nclock_freq=%02x no_sync=%02x no_dma=%d",
-			hd->clock_freq, hd->no_sync, hd->no_dma);
+		sprintf(tbuf, "\nclock_freq=%02x no_sync=%02x no_dma=%d"
+			" dma_mode=%02x fast=%d",
+			hd->clock_freq, hd->no_sync, hd->no_dma, hd->dma_mode, hd->fast);
 		strcat(bp, tbuf);
 		strcat(bp, "\nsync_xfer[] =       ");
 		for (x = 0; x < 7; x++) {
diff --git a/drivers/scsi/wd33c93.h b/drivers/scsi/wd33c93.h
index edcb036..61ffb86 100644
--- a/drivers/scsi/wd33c93.h
+++ b/drivers/scsi/wd33c93.h
@@ -155,6 +155,9 @@
 #define WD33C93_FS_12_15 OWNID_FS_12
 #define WD33C93_FS_16_20 OWNID_FS_16
 
+   /* pass input-clock explicitely. accepted mhz values are 8-10,12-20 */
+#define WD33C93_FS_MHZ(mhz) (mhz)
+
    /* Control register */
 #define CTRL_HSP     0x01
 #define CTRL_HA      0x02
@@ -253,6 +256,9 @@
     uchar            sync_stat[8];     /* status of sync negotiation per target */
     uchar            no_sync;          /* bitmask: don't do sync on these targets */
     uchar            no_dma;           /* set this flag to disable DMA */
+    uchar            dma_mode;         /* DMA Burst Mode or Single Byte DMA */
+    uchar            fast;             /* set this flag to enable Fast SCSI */
+    struct sx_period sx_table[9];      /* transfer periods for actual DTC-setting */
 #ifdef PROC_INTERFACE
     uchar            proc;             /* bitmask: what's in proc output */
 #ifdef PROC_STATISTICS
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index e8dd71d..ad9f321 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -262,7 +262,8 @@
 	select SERIAL_CORE
 	help
 	  This selects the ARM(R) AMBA(R) PrimeCell PL010 UART.  If you have
-	  an Integrator/AP or Integrator/PP2 platform, say Y or M here.
+	  an Integrator/AP or Integrator/PP2 platform, or if you have a
+	  Cirrus Logic EP93xx CPU, say Y or M here.
 
 	  If unsure, say N.
 
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index df45a7a..935f48f 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -33,12 +33,13 @@
 #include <linux/sysrq.h>
 #include <linux/tty_flip.h>
 #include <linux/platform_device.h>
+#include <linux/atmel_pdc.h>
 
 #include <asm/io.h>
 
 #include <asm/mach/serial_at91.h>
 #include <asm/arch/board.h>
-#include <asm/arch/at91_pdc.h>
+
 #ifdef CONFIG_ARM
 #include <asm/arch/cpu.h>
 #include <asm/arch/gpio.h>
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index 787a8f1..fa45599 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -285,7 +285,7 @@
 int __init cpm_uart_init_portdesc(void)
 {
 #if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2)
-	u32 addr;
+	u16 *addr;
 #endif
 	pr_debug("CPM uart[-]:init portdesc\n");
 
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index e216dcf..04cc88c 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -154,7 +154,7 @@
 {
 	struct circ_buf *xmit = &sport->port.info->xmit;
 
-	do {
+	while (!(UTS((u32)sport->port.membase) & UTS_TXFULL)) {
 		/* send xmit->buf[xmit->tail]
 		 * out the port here */
 		URTX0((u32)sport->port.membase) = xmit->buf[xmit->tail];
@@ -163,7 +163,7 @@
 		sport->port.icount.tx++;
 		if (uart_circ_empty(xmit))
 			break;
-	} while (!(UTS((u32)sport->port.membase) & UTS_TXFULL));
+	}
 
 	if (uart_circ_empty(xmit))
 		imx_stop_tx(&sport->port);
@@ -178,8 +178,7 @@
 
 	UCR1((u32)sport->port.membase) |= UCR1_TXMPTYEN;
 
-	if(UTS((u32)sport->port.membase) & UTS_TXEMPTY)
-		imx_transmit_buffer(sport);
+	imx_transmit_buffer(sport);
 }
 
 static irqreturn_t imx_rtsint(int irq, void *dev_id)
@@ -404,7 +403,8 @@
 	if (retval) goto error_out2;
 
 	retval = request_irq(sport->rtsirq, imx_rtsint,
-			     IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+			     (sport->rtsirq < IMX_IRQS) ? 0 :
+			       IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
 			     DRIVER_NAME, sport);
 	if (retval) goto error_out3;
 
@@ -678,7 +678,7 @@
 		.mapbase	= IMX_UART1_BASE, /* FIXME */
 		.irq		= UART1_MINT_RX,
 		.uartclk	= 16000000,
-		.fifosize	= 8,
+		.fifosize	= 32,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.ops		= &imx_pops,
 		.line		= 0,
@@ -694,7 +694,7 @@
 		.mapbase	= IMX_UART2_BASE, /* FIXME */
 		.irq		= UART2_MINT_RX,
 		.uartclk	= 16000000,
-		.fifosize	= 8,
+		.fifosize	= 32,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.ops		= &imx_pops,
 		.line		= 1,
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 955bbd6..8d24cd5 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -995,8 +995,10 @@
 	struct uart_port *port = dev_get_drvdata(&op->dev);
 	dev_set_drvdata(&op->dev, NULL);
 
-	if (port)
+	if (port) {
 		uart_remove_one_port(&mpc52xx_uart_driver, port);
+		irq_dispose_mapping(port->irq);
+	}
 
 	return 0;
 }
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index c2f1012..6b76bab 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -248,6 +248,10 @@
 		.multi	= 2,
 	}, {
 		.manfid	= MANFID_QUATECH,
+		.prodid	= PRODID_QUATECH_DUAL_RS232_G,
+		.multi	= 2,
+	}, {
+		.manfid	= MANFID_QUATECH,
 		.prodid	= PRODID_QUATECH_QUAD_RS232,
 		.multi	= 4,
 	}, {
@@ -891,6 +895,7 @@
 	PCMCIA_DEVICE_PROD_ID12("OEM      ", "C288MX     ", 0xb572d360, 0xd2385b7a),
 	PCMCIA_DEVICE_PROD_ID12("PCMCIA   ", "C336MX     ", 0x99bcafe9, 0xaa25bcab),
 	PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
+	PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d),
 	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
 	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
 	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 825bf88..8b7ff46 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -51,6 +51,7 @@
 obj-$(CONFIG_USB_ADUTUX)	+= misc/
 obj-$(CONFIG_USB_APPLEDISPLAY)	+= misc/
 obj-$(CONFIG_USB_AUERSWALD)	+= misc/
+obj-$(CONFIG_USB_BERRY_CHARGE)	+= misc/
 obj-$(CONFIG_USB_CYPRESS_CY7C63)+= misc/
 obj-$(CONFIG_USB_CYTHERM)	+= misc/
 obj-$(CONFIG_USB_EMI26)		+= misc/
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index dae4ef1..4973e14 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -61,6 +61,7 @@
 #include <linux/usb.h>
 #include <linux/firmware.h>
 #include <linux/ctype.h>
+#include <linux/sched.h>
 #include <linux/kthread.h>
 #include <linux/version.h>
 #include <linux/mutex.h>
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 9819962..d38a25f 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -326,10 +326,16 @@
 	struct tty_struct *tty = acm->tty;
 	struct acm_ru *rcv;
 	unsigned long flags;
-	int i = 0;
+	unsigned char throttled;
 	dbg("Entering acm_rx_tasklet");
 
-	if (!ACM_READY(acm) || acm->throttle)
+	if (!ACM_READY(acm))
+		return;
+
+	spin_lock(&acm->throttle_lock);
+	throttled = acm->throttle;
+	spin_unlock(&acm->throttle_lock);
+	if (throttled)
 		return;
 
 next_buffer:
@@ -346,22 +352,20 @@
 	dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size);
 
 	tty_buffer_request_room(tty, buf->size);
-	if (!acm->throttle)
+	spin_lock(&acm->throttle_lock);
+	throttled = acm->throttle;
+	spin_unlock(&acm->throttle_lock);
+	if (!throttled)
 		tty_insert_flip_string(tty, buf->base, buf->size);
 	tty_flip_buffer_push(tty);
 
-	spin_lock(&acm->throttle_lock);
-	if (acm->throttle) {
-		dbg("Throtteling noticed");
-		memmove(buf->base, buf->base + i, buf->size - i);
-		buf->size -= i;
-		spin_unlock(&acm->throttle_lock);
+	if (throttled) {
+		dbg("Throttling noticed");
 		spin_lock_irqsave(&acm->read_lock, flags);
 		list_add(&buf->list, &acm->filled_read_bufs);
 		spin_unlock_irqrestore(&acm->read_lock, flags);
 		return;
 	}
-	spin_unlock(&acm->throttle_lock);
 
 	spin_lock_irqsave(&acm->read_lock, flags);
 	list_add(&buf->list, &acm->spare_read_bufs);
@@ -467,7 +471,8 @@
 		goto bail_out;
 	}
 
-	if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS))
+	if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) &&
+	    (acm->ctrl_caps & USB_CDC_CAP_LINE))
 		goto full_bailout;
 
 	INIT_LIST_HEAD(&acm->spare_read_urbs);
@@ -480,6 +485,8 @@
 		list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
 	}
 
+	acm->throttle = 0;
+
 	tasklet_schedule(&acm->urb_task);
 
 done:
@@ -1092,6 +1099,10 @@
 	{ USB_DEVICE(0x0ace, 0x1611), /* ZyDAS 56K USB MODEM - new version */
 	.driver_info = SINGLE_RX_URB, /* firmware bug */
 	},
+	{ USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */
+	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+	},
+
 	/* control interfaces with various AT-command sets */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
 		USB_CDC_ACM_PROTO_AT_V25TER) },
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index a47c30b..aefc798 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -604,10 +604,6 @@
 	lock_kernel();
 	if (!st) {
 		st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);
-		if (!st) {
-			unlock_kernel();
-			return POLLIN;
-		}
 
 		/* we may have dropped BKL - need to check for having lost the race */
 		if (file->private_data) {
@@ -615,6 +611,11 @@
 			st = file->private_data;
 			goto lost_race;
 		}
+		/* we haven't lost - check for allocation failure now */
+		if (!st) {
+			unlock_kernel();
+			return POLLIN;
+		}
 
 		/*
 		 * need to prevent the module from being unloaded, since
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 2087766..274f14f 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -857,11 +857,11 @@
 
 static int proc_setconfig(struct dev_state *ps, void __user *arg)
 {
-	unsigned int u;
+	int u;
 	int status = 0;
  	struct usb_host_config *actconfig;
 
-	if (get_user(u, (unsigned int __user *)arg))
+	if (get_user(u, (int __user *)arg))
 		return -EFAULT;
 
  	actconfig = ps->dev->actconfig;
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 600d1bc..2aded26 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -743,6 +743,7 @@
  * usb_register_driver - register a USB interface driver
  * @new_driver: USB operations for the interface driver
  * @owner: module owner of this driver.
+ * @mod_name: module name string
  *
  * Registers a USB interface driver with the USB core.  The list of
  * unattached interfaces will be rescanned whenever a new driver is
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c
index 5e628ae..e0ec704 100644
--- a/drivers/usb/core/endpoint.c
+++ b/drivers/usb/core/endpoint.c
@@ -229,7 +229,7 @@
 	kref_init(&ep_class->kref);
 	ep_class->class = class_create(THIS_MODULE, "usb_endpoint");
 	if (IS_ERR(ep_class->class)) {
-		result = IS_ERR(ep_class->class);
+		result = PTR_ERR(ep_class->class);
 		goto class_create_error;
 	}
 
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index b531a4f..9bbcb20 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -184,7 +184,7 @@
 	/* if this is only an unbind, not a physical disconnect, then
 	 * unconfigure the device */
 	if (udev->actconfig)
-		usb_set_configuration(udev, 0);
+		usb_set_configuration(udev, -1);
 
 	usb_remove_sysfs_dev_files(udev);
 }
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 590ec82..50c0db1 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -44,6 +44,7 @@
 		struct usb_hub_status	hub;
 		struct usb_port_status	port;
 	}			*status;	/* buffer for status reports */
+	struct mutex		status_mutex;	/* for the status buffer */
 
 	int			error;		/* last reported error */
 	int			nerrors;	/* track consecutive errors */
@@ -535,6 +536,7 @@
 {
 	int ret;
 
+	mutex_lock(&hub->status_mutex);
 	ret = get_hub_status(hub->hdev, &hub->status->hub);
 	if (ret < 0)
 		dev_err (hub->intfdev,
@@ -544,6 +546,7 @@
 		*change = le16_to_cpu(hub->status->hub.wHubChange); 
 		ret = 0;
 	}
+	mutex_unlock(&hub->status_mutex);
 	return ret;
 }
 
@@ -617,6 +620,7 @@
 		ret = -ENOMEM;
 		goto fail;
 	}
+	mutex_init(&hub->status_mutex);
 
 	hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
 	if (!hub->descriptor) {
@@ -1396,6 +1400,7 @@
 {
 	int ret;
 
+	mutex_lock(&hub->status_mutex);
 	ret = get_port_status(hub->hdev, port1, &hub->status->port);
 	if (ret < 4) {
 		dev_err (hub->intfdev,
@@ -1407,6 +1412,7 @@
 		*change = le16_to_cpu(hub->status->port.wPortChange); 
 		ret = 0;
 	}
+	mutex_unlock(&hub->status_mutex);
 	return ret;
 }
 
@@ -1904,6 +1910,7 @@
 	struct usb_hub		*hub = usb_get_intfdata (intf);
 	struct usb_device	*hdev = hub->hdev;
 	unsigned		port1;
+	int			status = 0;
 
 	/* fail if children aren't already suspended */
 	for (port1 = 1; port1 <= hdev->maxchild; port1++) {
@@ -1927,24 +1934,18 @@
 
 	dev_dbg(&intf->dev, "%s\n", __FUNCTION__);
 
-	/* "global suspend" of the downstream HC-to-USB interface */
-	if (!hdev->parent) {
-		struct usb_bus	*bus = hdev->bus;
-		if (bus) {
-			int	status = hcd_bus_suspend (bus);
-
-			if (status != 0) {
-				dev_dbg(&hdev->dev, "'global' suspend %d\n",
-					status);
-				return status;
-			}
-		} else
-			return -EOPNOTSUPP;
-	}
-
 	/* stop khubd and related activity */
 	hub_quiesce(hub);
-	return 0;
+
+	/* "global suspend" of the downstream HC-to-USB interface */
+	if (!hdev->parent) {
+		status = hcd_bus_suspend(hdev->bus);
+		if (status != 0) {
+			dev_dbg(&hdev->dev, "'global' suspend %d\n", status);
+			hub_activate(hub);
+		}
+	}
+	return status;
 }
 
 static int hub_resume(struct usb_interface *intf)
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 8aca357..74edaea 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1316,6 +1316,14 @@
  * use this kind of configurability; many devices only have one
  * configuration.
  *
+ * @configuration is the value of the configuration to be installed.
+ * According to the USB spec (e.g. section 9.1.1.5), configuration values
+ * must be non-zero; a value of zero indicates that the device in
+ * unconfigured.  However some devices erroneously use 0 as one of their
+ * configuration values.  To help manage such devices, this routine will
+ * accept @configuration = -1 as indicating the device should be put in
+ * an unconfigured state.
+ *
  * USB device configurations may affect Linux interoperability,
  * power consumption and the functionality available.  For example,
  * the default configuration is limited to using 100mA of bus power,
@@ -1347,10 +1355,15 @@
 	struct usb_interface **new_interfaces = NULL;
 	int n, nintf;
 
-	for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
-		if (dev->config[i].desc.bConfigurationValue == configuration) {
-			cp = &dev->config[i];
-			break;
+	if (configuration == -1)
+		configuration = 0;
+	else {
+		for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
+			if (dev->config[i].desc.bConfigurationValue ==
+					configuration) {
+				cp = &dev->config[i];
+				break;
+			}
 		}
 	}
 	if ((!cp && configuration != 0))
@@ -1359,6 +1372,7 @@
 	/* The USB spec says configuration 0 means unconfigured.
 	 * But if a device includes a configuration numbered 0,
 	 * we will accept it as a correctly configured state.
+	 * Use -1 if you really want to unconfigure the device.
 	 */
 	if (cp && configuration == 0)
 		dev_warn(&dev->dev, "config 0 descriptor??\n");
diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h
index 627a5a2..7f31a49 100644
--- a/drivers/usb/core/otg_whitelist.h
+++ b/drivers/usb/core/otg_whitelist.h
@@ -31,7 +31,7 @@
 { USB_DEVICE_INFO(7, 1, 3) },
 #endif
 
-#ifdef	CONFIG_USB_CDCETHER
+#ifdef	CONFIG_USB_NET_CDCETHER
 /* Linux-USB CDC Ethernet gadget */
 { USB_DEVICE(0x0525, 0xa4a1), },
 /* Linux-USB CDC Ethernet + RNDIS gadget */
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 4eaa0ee..0edfbaf 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -63,7 +63,7 @@
 	struct usb_device	*udev = to_usb_device(dev);
 	int			config, value;
 
-	if (sscanf(buf, "%u", &config) != 1 || config > 255)
+	if (sscanf(buf, "%d", &config) != 1 || config < -1 || config > 255)
 		return -EINVAL;
 	usb_lock_device(udev);
 	value = usb_set_configuration(udev, config);
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 36b36e0..a467780 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -784,7 +784,7 @@
 	return status;
 }
 
-static struct usb_ep_ops at91_ep_ops = {
+static const struct usb_ep_ops at91_ep_ops = {
 	.enable		= at91_ep_enable,
 	.disable	= at91_ep_disable,
 	.alloc_request	= at91_ep_alloc_request,
@@ -912,7 +912,7 @@
 		at91_udp_write(udc, AT91_UDP_TXVC, 0);
 		if (cpu_is_at91rm9200())
 			at91_set_gpio_value(udc->board.pullup_pin, 1);
-		else if (cpu_is_at91sam9260()) {
+		else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) {
 			u32	txvc = at91_udp_read(udc, AT91_UDP_TXVC);
 
 			txvc |= AT91_UDP_TXVC_PUON;
@@ -929,7 +929,7 @@
 		at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
 		if (cpu_is_at91rm9200())
 			at91_set_gpio_value(udc->board.pullup_pin, 0);
-		else if (cpu_is_at91sam9260()) {
+		else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) {
 			u32	txvc = at91_udp_read(udc, AT91_UDP_TXVC);
 
 			txvc &= ~AT91_UDP_TXVC_PUON;
@@ -1651,7 +1651,7 @@
 	pullup(platform_get_drvdata(dev), 0);
 }
 
-static int __devinit at91udc_probe(struct platform_device *pdev)
+static int __init at91udc_probe(struct platform_device *pdev)
 {
 	struct device	*dev = &pdev->dev;
 	struct at91_udc	*udc;
@@ -1762,7 +1762,7 @@
 	return retval;
 }
 
-static int __devexit at91udc_remove(struct platform_device *pdev)
+static int __exit at91udc_remove(struct platform_device *pdev)
 {
 	struct at91_udc *udc = platform_get_drvdata(pdev);
 	struct resource *res;
@@ -1836,8 +1836,7 @@
 #endif
 
 static struct platform_driver at91_udc = {
-	.probe		= at91udc_probe,
-	.remove		= __devexit_p(at91udc_remove),
+	.remove		= __exit_p(at91udc_remove),
 	.shutdown	= at91udc_shutdown,
 	.suspend	= at91udc_suspend,
 	.resume		= at91udc_resume,
@@ -1847,13 +1846,13 @@
 	},
 };
 
-static int __devinit udc_init_module(void)
+static int __init udc_init_module(void)
 {
-	return platform_driver_register(&at91_udc);
+	return platform_driver_probe(&at91_udc, at91udc_probe);
 }
 module_init(udc_init_module);
 
-static void __devexit udc_exit_module(void)
+static void __exit udc_exit_module(void)
 {
 	platform_driver_unregister(&at91_udc);
 }
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 27904a5..f01890d 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -155,7 +155,7 @@
 	struct pxa2xx_udc_mach_info		*mach = the_controller->mach;
 
 	if (mach->gpio_vbus)
-		return pxa_gpio_get(mach->gpio_vbus);
+		return udc_gpio_get(mach->gpio_vbus);
 	if (mach->udc_is_connected)
 		return mach->udc_is_connected();
 	return 1;
@@ -167,7 +167,7 @@
 	struct pxa2xx_udc_mach_info		*mach = the_controller->mach;
 
 	if (mach->gpio_pullup)
-		pxa_gpio_set(mach->gpio_pullup, 0);
+		udc_gpio_set(mach->gpio_pullup, 0);
 	else if (mach->udc_command)
 		mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
 }
@@ -177,7 +177,7 @@
 	struct pxa2xx_udc_mach_info		*mach = the_controller->mach;
 
 	if (mach->gpio_pullup)
-		pxa_gpio_set(mach->gpio_pullup, 1);
+		udc_gpio_set(mach->gpio_pullup, 1);
 	else if (mach->udc_command)
 		mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
 }
@@ -1755,7 +1755,7 @@
 static irqreturn_t udc_vbus_irq(int irq, void *_dev)
 {
 	struct pxa2xx_udc	*dev = _dev;
-	int			vbus = pxa_gpio_get(dev->mach->gpio_vbus);
+	int			vbus = udc_gpio_get(dev->mach->gpio_vbus);
 
 	pxa2xx_udc_vbus_session(&dev->gadget, vbus);
 	return IRQ_HANDLED;
@@ -2545,15 +2545,13 @@
 	dev->dev = &pdev->dev;
 	dev->mach = pdev->dev.platform_data;
 	if (dev->mach->gpio_vbus) {
-		vbus_irq = IRQ_GPIO(dev->mach->gpio_vbus & GPIO_MD_MASK_NR);
-		pxa_gpio_mode((dev->mach->gpio_vbus & GPIO_MD_MASK_NR)
-				| GPIO_IN);
+		udc_gpio_init_vbus(dev->mach->gpio_vbus);
+		vbus_irq = udc_gpio_to_irq(dev->mach->gpio_vbus);
 		set_irq_type(vbus_irq, IRQT_BOTHEDGE);
 	} else
 		vbus_irq = 0;
 	if (dev->mach->gpio_pullup)
-		pxa_gpio_mode((dev->mach->gpio_pullup & GPIO_MD_MASK_NR)
-				| GPIO_OUT | GPIO_DFLT_LOW);
+		udc_gpio_init_pullup(dev->mach->gpio_pullup);
 
 	init_timer(&dev->timer);
 	dev->timer.function = udc_watchdog;
diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h
index 8e598c8..773e549 100644
--- a/drivers/usb/gadget/pxa2xx_udc.h
+++ b/drivers/usb/gadget/pxa2xx_udc.h
@@ -177,21 +177,6 @@
 
 static struct pxa2xx_udc *the_controller;
 
-static inline int pxa_gpio_get(unsigned gpio)
-{
-	return (GPLR(gpio) & GPIO_bit(gpio)) != 0;
-}
-
-static inline void pxa_gpio_set(unsigned gpio, int is_on)
-{
-	int mask = GPIO_bit(gpio);
-
-	if (is_on)
-		GPSR(gpio) = mask;
-	else
-		GPCR(gpio) = mask;
-}
-
 /*-------------------------------------------------------------------------*/
 
 /*
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index e6c19aa..e552668 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -1699,6 +1699,7 @@
 			memcpy(&port->port_line_coding, req->buf, ret);
 			spin_unlock(&port->port_lock);
 		}
+		ret = 0;
 		break;
 
 	case USB_CDC_REQ_GET_LINE_CODING:
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 246afea..43eddae 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -322,7 +322,7 @@
 
 #else
 
-/* troubleshooting help: expose state in driverfs */
+/* troubleshooting help: expose state in sysfs */
 
 #define speed_char(info1) ({ char tmp; \
 		switch (info1 & (3 << 12)) { \
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 185721d..a740564 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -42,6 +42,9 @@
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/unaligned.h>
+#ifdef CONFIG_PPC_PS3
+#include <asm/firmware.h>
+#endif
 
 
 /*-------------------------------------------------------------------------*/
@@ -299,6 +302,19 @@
 	spin_unlock_irqrestore (&ehci->lock, flags);
 }
 
+/* On some systems, leaving remote wakeup enabled prevents system shutdown.
+ * The firmware seems to think that powering off is a wakeup event!
+ * This routine turns off remote wakeup and everything else, on all ports.
+ */
+static void ehci_turn_off_all_ports(struct ehci_hcd *ehci)
+{
+	int	port = HCS_N_PORTS(ehci->hcs_params);
+
+	while (port--)
+		ehci_writel(ehci, PORT_RWC_BITS,
+				&ehci->regs->port_status[port]);
+}
+
 /* ehci_shutdown kick in for silicon on any bus (not just pci, etc).
  * This forcibly disables dma and IRQs, helping kexec and other cases
  * where the next system software may expect clean state.
@@ -310,9 +326,13 @@
 
 	ehci = hcd_to_ehci (hcd);
 	(void) ehci_halt (ehci);
+	ehci_turn_off_all_ports(ehci);
 
 	/* make BIOS/etc use companion controller during reboot */
 	ehci_writel(ehci, 0, &ehci->regs->configured_flag);
+
+	/* unblock posted writes */
+	ehci_readl(ehci, &ehci->regs->configured_flag);
 }
 
 static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
@@ -951,15 +971,18 @@
 #endif
 
 #ifdef PS3_SYSTEM_BUS_DRIVER
-	retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER);
-	if (retval < 0) {
+	if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
+		retval = ps3_system_bus_driver_register(
+				&PS3_SYSTEM_BUS_DRIVER);
+		if (retval < 0) {
 #ifdef PLATFORM_DRIVER
-		platform_driver_unregister(&PLATFORM_DRIVER);
+			platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
 #ifdef PCI_DRIVER
-		pci_unregister_driver(&PCI_DRIVER);
+			pci_unregister_driver(&PCI_DRIVER);
 #endif
-		return retval;
+			return retval;
+		}
 	}
 #endif
 
@@ -976,7 +999,8 @@
 	pci_unregister_driver(&PCI_DRIVER);
 #endif
 #ifdef PS3_SYSTEM_BUS_DRIVER
-	ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+	if (firmware_has_feature(FW_FEATURE_PS3_LV1))
+		ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
 #endif
 }
 module_exit(ehci_hcd_cleanup);
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 0d83c6d..9af529d 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -36,6 +36,8 @@
 	int			port;
 	int			mask;
 
+	ehci_dbg(ehci, "suspend root hub\n");
+
 	if (time_before (jiffies, ehci->next_statechange))
 		msleep(5);
 
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 2718b5d..46873f2 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1577,7 +1577,7 @@
 
 #define resource_len(r) (((r)->end - (r)->start) + 1)
 
-static int __init isp116x_probe(struct platform_device *pdev)
+static int __devinit isp116x_probe(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd;
 	struct isp116x *isp116x;
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 9303464..d849c80 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -18,19 +18,38 @@
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
 #include <asm/arch/board.h>
+#include <asm/arch/cpu.h>
 
 #ifndef CONFIG_ARCH_AT91
 #error "CONFIG_ARCH_AT91 must be defined."
 #endif
 
-/* interface and function clocks */
-static struct clk *iclk, *fclk;
+/* interface and function clocks; sometimes also an AHB clock */
+static struct clk *iclk, *fclk, *hclk;
 static int clocked;
 
 extern int usb_disabled(void);
 
 /*-------------------------------------------------------------------------*/
 
+static void at91_start_clock(void)
+{
+	if (cpu_is_at91sam9261())
+		clk_enable(hclk);
+	clk_enable(iclk);
+	clk_enable(fclk);
+	clocked = 1;
+}
+
+static void at91_stop_clock(void)
+{
+	clk_disable(fclk);
+	clk_disable(iclk);
+	if (cpu_is_at91sam9261())
+		clk_disable(hclk);
+	clocked = 0;
+}
+
 static void at91_start_hc(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
@@ -41,9 +60,7 @@
 	/*
 	 * Start the USB clocks.
 	 */
-	clk_enable(iclk);
-	clk_enable(fclk);
-	clocked = 1;
+	at91_start_clock();
 
 	/*
 	 * The USB host controller must remain in reset.
@@ -66,9 +83,7 @@
 	/*
 	 * Stop the USB clocks.
 	 */
-	clk_disable(fclk);
-	clk_disable(iclk);
-	clocked = 0;
+	at91_stop_clock();
 }
 
 
@@ -126,6 +141,8 @@
 
 	iclk = clk_get(&pdev->dev, "ohci_clk");
 	fclk = clk_get(&pdev->dev, "uhpck");
+	if (cpu_is_at91sam9261())
+		hclk = clk_get(&pdev->dev, "hck0");
 
 	at91_start_hc(pdev);
 	ohci_hcd_init(hcd_to_ohci(hcd));
@@ -137,6 +154,8 @@
 	/* Error handling */
 	at91_stop_hc(pdev);
 
+	if (cpu_is_at91sam9261())
+		clk_put(hclk);
 	clk_put(fclk);
 	clk_put(iclk);
 
@@ -171,9 +190,11 @@
 	iounmap(hcd->regs);
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 
+	if (cpu_is_at91sam9261())
+		clk_put(hclk);
 	clk_put(fclk);
 	clk_put(iclk);
-	fclk = iclk = NULL;
+	fclk = iclk = hclk = NULL;
 
 	dev_set_drvdata(&pdev->dev, NULL);
 	return 0;
@@ -280,9 +301,7 @@
 	 */
 	if (at91_suspend_entering_slow_clock()) {
 		ohci_usb_reset (ohci);
-		clk_disable(fclk);
-		clk_disable(iclk);
-		clocked = 0;
+		at91_stop_clock();
 	}
 
 	return 0;
@@ -295,11 +314,8 @@
 	if (device_may_wakeup(&pdev->dev))
 		disable_irq_wake(hcd->irq);
 
-	if (!clocked) {
-		clk_enable(iclk);
-		clk_enable(fclk);
-		clocked = 1;
-	}
+	if (!clocked)
+		at91_start_clock();
 
 	return 0;
 }
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index fa6a7ce..f0d29ed 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -42,6 +42,9 @@
 #include <asm/system.h>
 #include <asm/unaligned.h>
 #include <asm/byteorder.h>
+#ifdef CONFIG_PPC_PS3
+#include <asm/firmware.h>
+#endif
 
 #include "../core/hcd.h"
 
@@ -944,9 +947,12 @@
 		sizeof (struct ed), sizeof (struct td));
 
 #ifdef PS3_SYSTEM_BUS_DRIVER
-	retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER);
-	if (retval < 0)
-		goto error_ps3;
+	if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
+		retval = ps3_system_bus_driver_register(
+				&PS3_SYSTEM_BUS_DRIVER);
+		if (retval < 0)
+			goto error_ps3;
+	}
 #endif
 
 #ifdef PLATFORM_DRIVER
@@ -992,7 +998,8 @@
  error_platform:
 #endif
 #ifdef PS3_SYSTEM_BUS_DRIVER
-	ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+	if (firmware_has_feature(FW_FEATURE_PS3_LV1))
+		ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
  error_ps3:
 #endif
 	return retval;
@@ -1014,7 +1021,8 @@
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
 #ifdef PS3_SYSTEM_BUS_DRIVER
-	ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+	if (firmware_has_feature(FW_FEATURE_PS3_LV1))
+		ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
 #endif
 }
 module_exit(ohci_hcd_mod_exit);
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index 2e71d3c..69a9f3b 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -58,13 +58,17 @@
 	  devices.
 
 config LOGITECH_FF
-	bool "Logitech WingMan *3D support"
+	bool "Logitech devices support"
 	depends on HID_FF
 	select INPUT_FF_MEMLESS if USB_HID
 	help
 	  Say Y here if you have one of these devices:
 	  - Logitech WingMan Cordless RumblePad
+	  - Logitech WingMan Cordless RumblePad 2
 	  - Logitech WingMan Force 3D
+	  - Logitech Formula Force EX
+	  - Logitech MOMO Force wheel
+
 	  and if you want to enable force feedback for them.
 	  Note: if you say N here, this device will still be supported, but without
 	  force feedback.
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 4d8ed3d..ef09952 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -515,6 +515,7 @@
 
 #define USB_VENDOR_ID_TURBOX		0x062a
 #define USB_DEVICE_ID_TURBOX_KEYBOARD	0x0201
+#define USB_VENDOR_ID_CIDC		0x1677
 
 /*
  * Initialize all reports
@@ -548,7 +549,6 @@
 }
 
 #define USB_VENDOR_ID_GTCO		0x078c
-#define USB_VENDOR_ID_GTCO_IPANEL_2     0x5543
 #define USB_DEVICE_ID_GTCO_90		0x0090
 #define USB_DEVICE_ID_GTCO_100		0x0100
 #define USB_DEVICE_ID_GTCO_101		0x0101
@@ -594,8 +594,6 @@
 #define USB_DEVICE_ID_GTCO_1004		0x1004
 #define USB_DEVICE_ID_GTCO_1005		0x1005
 #define USB_DEVICE_ID_GTCO_1006		0x1006
-#define USB_DEVICE_ID_GTCO_8		0x0008
-#define USB_DEVICE_ID_GTCO_d            0x000d
 
 #define USB_VENDOR_ID_WACOM		0x056a
 
@@ -854,8 +852,6 @@
 	{ USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE },
-	{ USB_VENDOR_ID_GTCO_IPANEL_2, USB_DEVICE_ID_GTCO_8, HID_QUIRK_IGNORE },
-	{ USB_VENDOR_ID_GTCO_IPANEL_2, USB_DEVICE_ID_GTCO_d, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE },
@@ -953,6 +949,8 @@
 
 	{ USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER },
 
+	{ USB_VENDOR_ID_CIDC, 0x0103, HID_QUIRK_IGNORE },
+
 	{ 0, 0 }
 };
 
diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c
index bc7f8e6..e431faa 100644
--- a/drivers/usb/input/hid-ff.c
+++ b/drivers/usb/input/hid-ff.c
@@ -54,9 +54,10 @@
 static struct hid_ff_initializer inits[] = {
 #ifdef CONFIG_LOGITECH_FF
 	{ 0x46d, 0xc211, hid_lgff_init }, /* Logitech Cordless rumble pad */
-	{ 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */
-	{ 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */
 	{ 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */
+	{ 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */
+	{ 0x46d, 0xc294, hid_lgff_init }, /* Logitech Formula Force EX */
+	{ 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */
 	{ 0x46d, 0xca03, hid_lgff_init }, /* Logitech MOMO force wheel */
 #endif
 #ifdef CONFIG_PANTHERLORD_FF
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
index 4df0968..e6f3af3 100644
--- a/drivers/usb/input/hid-lgff.c
+++ b/drivers/usb/input/hid-lgff.c
@@ -52,8 +52,9 @@
 	{ 0x046d, 0xc211, ff_rumble },
 	{ 0x046d, 0xc219, ff_rumble },
 	{ 0x046d, 0xc283, ff_joystick },
+	{ 0x046d, 0xc294, ff_joystick },
+	{ 0x046d, 0xc295, ff_joystick },
 	{ 0x046d, 0xca03, ff_joystick },
-	{ 0x0000, 0x0000, ff_joystick }
 };
 
 static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
@@ -105,8 +106,9 @@
 	struct input_dev *dev = hidinput->input;
 	struct hid_report *report;
 	struct hid_field *field;
+	const signed short *ff_bits = ff_joystick;
 	int error;
-	int i, j;
+	int i;
 
 	/* Find the report to use */
 	if (list_empty(report_list)) {
@@ -130,12 +132,14 @@
 	for (i = 0; i < ARRAY_SIZE(devices); i++) {
 		if (dev->id.vendor == devices[i].idVendor &&
 		    dev->id.product == devices[i].idProduct) {
-			for (j = 0; devices[i].ff[j] >= 0; j++)
-				set_bit(devices[i].ff[j], dev->ffbit);
+			ff_bits = devices[i].ff;
 			break;
 		}
 	}
 
+	for (i = 0; ff_bits[i] >= 0; i++)
+		set_bit(ff_bits[i], dev->ffbit);
+
 	error = input_ff_create_memless(dev, NULL, hid_lgff_play);
 	if (error)
 		return error;
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index a74bf86..4907e8b 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -88,6 +88,17 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called usblcd.
 
+config USB_BERRY_CHARGE
+	tristate "USB BlackBerry recharge support"
+	depends on USB
+	help
+	  Say Y here if you want to connect a BlackBerry device to your
+	  computer's USB port and have it automatically switch to "recharge"
+	  mode.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called berry_charge.
+
 config USB_LED
 	tristate "USB LED driver support"
 	depends on USB
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index 2cba07d..dac2d5b 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -6,6 +6,7 @@
 obj-$(CONFIG_USB_ADUTUX)	+= adutux.o
 obj-$(CONFIG_USB_APPLEDISPLAY)	+= appledisplay.o
 obj-$(CONFIG_USB_AUERSWALD)	+= auerswald.o
+obj-$(CONFIG_USB_BERRY_CHARGE)	+= berry_charge.o
 obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o
 obj-$(CONFIG_USB_CYTHERM)	+= cytherm.o
 obj-$(CONFIG_USB_EMI26)		+= emi26.o
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
index 32f0e3a..e573c8b 100644
--- a/drivers/usb/misc/appledisplay.c
+++ b/drivers/usb/misc/appledisplay.c
@@ -281,8 +281,8 @@
 	/* Register backlight device */
 	snprintf(bl_name, sizeof(bl_name), "appledisplay%d",
 		atomic_inc_return(&count_displays) - 1);
-	pdata->bd = backlight_device_register(bl_name, NULL,
-		pdata, &appledisplay_bl_data);
+	pdata->bd = backlight_device_register(bl_name, NULL, pdata,
+						&appledisplay_bl_data);
 	if (IS_ERR(pdata->bd)) {
 		err("appledisplay: Backlight registration failed");
 		goto error;
diff --git a/drivers/usb/misc/berry_charge.c b/drivers/usb/misc/berry_charge.c
new file mode 100644
index 0000000..60893c6
--- /dev/null
+++ b/drivers/usb/misc/berry_charge.c
@@ -0,0 +1,140 @@
+/*
+ * USB BlackBerry charging module
+ *
+ * Copyright (C) 2007 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ *	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, version 2.
+ *
+ * Information on how to switch configs was taken by the bcharge.cc file
+ * created by the barry.sf.net project.
+ *
+ * bcharge.cc has the following copyright:
+ * 	Copyright (C) 2006, Net Direct Inc. (http://www.netdirect.ca/)
+ * and is released under the GPLv2.
+ *
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#define RIM_VENDOR		0x0fca
+#define BLACKBERRY		0x0001
+
+static int debug;
+
+#ifdef dbg
+#undef dbg
+#endif
+#define dbg(dev, format, arg...)				\
+	if (debug)						\
+		dev_printk(KERN_DEBUG , dev , format , ## arg)
+
+static struct usb_device_id id_table [] = {
+	{ USB_DEVICE(RIM_VENDOR, BLACKBERRY) },
+	{ },					/* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static int magic_charge(struct usb_device *udev)
+{
+	char *dummy_buffer = kzalloc(2, GFP_KERNEL);
+	int retval;
+
+	if (!dummy_buffer)
+		return -ENOMEM;
+
+	/* send two magic commands and then set the configuration.  The device
+	 * will then reset itself with the new power usage and should start
+	 * charging. */
+
+	/* Note, with testing, it only seems that the first message is really
+	 * needed (at least for the 8700c), but to be safe, we emulate what
+	 * other operating systems seem to be sending to their device.  We
+	 * really need to get some specs for this device to be sure about what
+	 * is going on here.
+	 */
+	dbg(&udev->dev, "Sending first magic command\n");
+	retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+				 0xa5, 0xc0, 0, 1, dummy_buffer, 2, 100);
+	if (retval != 2) {
+		dev_err(&udev->dev, "First magic command failed: %d.\n",
+			retval);
+		return retval;
+	}
+
+	dbg(&udev->dev, "Sending first magic command\n");
+	retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+				 0xa2, 0x40, 0, 1, dummy_buffer, 0, 100);
+	if (retval != 0) {
+		dev_err(&udev->dev, "Second magic command failed: %d.\n",
+			retval);
+		return retval;
+	}
+
+	dbg(&udev->dev, "Calling set_configuration\n");
+	retval = usb_driver_set_configuration(udev, 1);
+	if (retval)
+		dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval);
+
+	return retval;
+}
+
+static int berry_probe(struct usb_interface *intf,
+		       const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+
+	dbg(&udev->dev, "Power is set to %dmA\n",
+	    udev->actconfig->desc.bMaxPower * 2);
+
+	/* check the power usage so we don't try to enable something that is
+	 * already enabled */
+	if ((udev->actconfig->desc.bMaxPower * 2) == 500) {
+		dbg(&udev->dev, "device is already charging, power is "
+		    "set to %dmA\n", udev->actconfig->desc.bMaxPower * 2);
+		return -ENODEV;
+	}
+
+	/* turn the power on */
+	magic_charge(udev);
+
+	/* we don't really want to bind to the device, userspace programs can
+	 * handle the syncing just fine, so get outta here. */
+	return -ENODEV;
+}
+
+static void berry_disconnect(struct usb_interface *intf)
+{
+}
+
+static struct usb_driver berry_driver = {
+	.name =		"berry_charge",
+	.probe =	berry_probe,
+	.disconnect =	berry_disconnect,
+	.id_table =	id_table,
+};
+
+static int __init berry_init(void)
+{
+	return usb_register(&berry_driver);
+}
+
+static void __exit berry_exit(void)
+{
+	usb_deregister(&berry_driver);
+}
+
+module_init(berry_init);
+module_exit(berry_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig
index a2b94ef5..0f3d7db 100644
--- a/drivers/usb/net/Kconfig
+++ b/drivers/usb/net/Kconfig
@@ -84,6 +84,7 @@
 config USB_RTL8150
 	tristate "USB RTL8150 based ethernet device support (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
+	select MII
 	help
 	  Say Y here if you have RTL8150 based usb-ethernet adapter.
 	  Send me <petkan@users.sourceforge.net> any comments you may have.
@@ -98,7 +99,7 @@
 
 config USB_USBNET
 	tristate "Multi-purpose USB Networking Framework"
-	select MII if USBNET_MII != n
+	select MII if USB_USBNET_MII != n
 	---help---
 	  This driver supports several kinds of network links over USB,
 	  with "minidrivers" built around a common network driver core
@@ -239,6 +240,7 @@
 config USB_NET_CDC_SUBSET
 	tristate "Simple USB Network Links (CDC Ethernet subset)"
 	depends on USB_USBNET
+	default y
 	help
 	  This driver module supports USB network devices that can work
 	  without any device-specific information.  Select it if you have
@@ -298,6 +300,13 @@
 	  Choose this option to support the usb networking links used
 	  by some sample firmware from Epson.
 
+config USB_KC2190
+	boolean "KT Technology KC2190 based cables (InstaNet)"
+	depends on USB_NET_CDC_SUBSET && EXPERIMENTAL
+	help
+	  Choose this option if you're using a host-to-host cable
+	  with one of these chips.
+
 config USB_NET_ZAURUS
 	tristate "Sharp Zaurus (stock ROMs) and compatible"
 	depends on USB_USBNET
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c
index bd357e1..7ef2e4b 100644
--- a/drivers/usb/net/asix.c
+++ b/drivers/usb/net/asix.c
@@ -351,9 +351,11 @@
 
 	skb_push(skb, 4);
 	packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4);
+	cpu_to_le32s(&packet_len);
 	memcpy(skb->data, &packet_len, sizeof(packet_len));
 
 	if ((skb->len % 512) == 0) {
+		cpu_to_le32s(&padbytes);
 		memcpy( skb->tail, &padbytes, sizeof(padbytes));
 		skb_put(skb, sizeof(padbytes));
 	}
diff --git a/drivers/usb/net/cdc_subset.c b/drivers/usb/net/cdc_subset.c
index ae8fb06..bc62b01 100644
--- a/drivers/usb/net/cdc_subset.c
+++ b/drivers/usb/net/cdc_subset.c
@@ -79,13 +79,19 @@
  *
  * ALi M5632 driver ... does high speed
  *
+ * NOTE that the MS-Windows drivers for this chip use some funky and
+ * (naturally) undocumented 7-byte prefix to each packet, so this is a
+ * case where we don't currently interoperate.  Also, once you unplug
+ * one end of the cable, you need to replug the other end too ... since
+ * chip docs are unavailable, there's no way to reset the relevant state
+ * short of a power cycle.
+ *
  *-------------------------------------------------------------------------*/
 
 static const struct driver_info	ali_m5632_info = {
 	.description =	"ALi M5632",
 };
 
-
 #endif
 
 
@@ -159,6 +165,11 @@
 #endif	/* CONFIG_USB_EPSON2888 */
 
 
+/*-------------------------------------------------------------------------
+ *
+ * info from Jonathan McDowell <noodles@earth.li>
+ *
+ *-------------------------------------------------------------------------*/
 #ifdef CONFIG_USB_KC2190
 #define HAVE_HARDWARE
 static const struct driver_info kc2190_info = {
@@ -223,6 +234,10 @@
 	USB_DEVICE (0x0402, 0x5632),	// ALi defaults
 	.driver_info =	(unsigned long) &ali_m5632_info,
 },
+{
+	USB_DEVICE (0x182d,0x207c),	// SiteCom CN-124
+	.driver_info =	(unsigned long) &ali_m5632_info,
+},
 #endif
 
 #ifdef	CONFIG_USB_AN2720
@@ -314,13 +329,13 @@
 
 static int __init cdc_subset_init(void)
 {
- 	return usb_register(&cdc_subset_driver);
+	return usb_register(&cdc_subset_driver);
 }
 module_init(cdc_subset_init);
 
 static void __exit cdc_subset_exit(void)
 {
- 	usb_deregister(&cdc_subset_driver);
+	usb_deregister(&cdc_subset_driver);
 }
 module_exit(cdc_subset_exit);
 
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index 43ba61a..de69b18 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -147,7 +147,7 @@
 		if (tmp < 0)
 			return tmp;
 	}
-	
+
 	dev->in = usb_rcvbulkpipe (dev->udev,
 			in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
 	dev->out = usb_sndbulkpipe (dev->udev,
@@ -327,7 +327,7 @@
 	if (netif_running (dev->net)
 			&& netif_device_present (dev->net)
 			&& !test_bit (EVENT_RX_HALT, &dev->flags)) {
-		switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){ 
+		switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){
 		case -EPIPE:
 			usbnet_defer_kevent (dev, EVENT_RX_HALT);
 			break;
@@ -443,7 +443,7 @@
 	    case -EOVERFLOW:
 		dev->stats.rx_over_errors++;
 		// FALLTHROUGH
-	    
+
 	    default:
 		entry->state = rx_cleanup;
 		dev->stats.rx_errors++;
@@ -560,7 +560,7 @@
 
 	if (netif_msg_ifdown (dev))
 		devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld",
-			dev->stats.rx_packets, dev->stats.tx_packets, 
+			dev->stats.rx_packets, dev->stats.tx_packets,
 			dev->stats.rx_errors, dev->stats.tx_errors
 			);
 
@@ -578,7 +578,7 @@
 			devdbg (dev, "waited for %d urb completions", temp);
 	}
 	dev->wait = NULL;
-	remove_wait_queue (&unlink_wakeup, &wait); 
+	remove_wait_queue (&unlink_wakeup, &wait);
 
 	usb_kill_urb(dev->interrupt);
 
@@ -834,7 +834,7 @@
 	}
 
 	if (test_bit (EVENT_LINK_RESET, &dev->flags)) {
-		struct driver_info 	*info = dev->driver_info;
+		struct driver_info	*info = dev->driver_info;
 		int			retval = 0;
 
 		clear_bit (EVENT_LINK_RESET, &dev->flags);
@@ -1066,7 +1066,7 @@
  * USB Device Driver support
  *
  *-------------------------------------------------------------------------*/
- 
+
 // precondition: never called in_interrupt
 
 void usbnet_disconnect (struct usb_interface *intf)
@@ -1087,7 +1087,7 @@
 			intf->dev.driver->name,
 			xdev->bus->bus_name, xdev->devpath,
 			dev->driver_info->description);
-	
+
 	net = dev->net;
 	unregister_netdev (net);
 
@@ -1111,7 +1111,7 @@
 usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 {
 	struct usbnet			*dev;
-	struct net_device 		*net;
+	struct net_device		*net;
 	struct usb_host_interface	*interface;
 	struct driver_info		*info;
 	struct usb_device		*xdev;
@@ -1181,6 +1181,9 @@
 	// NOTE net->name still not usable ...
 	if (info->bind) {
 		status = info->bind (dev, udev);
+		if (status < 0)
+			goto out1;
+
 		// heuristic:  "usb%d" for links we know are two-host,
 		// else "eth%d" when there's reasonable doubt.  userspace
 		// can rename the link if it knows better.
@@ -1207,12 +1210,12 @@
 	if (status == 0 && dev->status)
 		status = init_status (dev, udev);
 	if (status < 0)
-		goto out1;
+		goto out3;
 
 	if (!dev->rx_urb_size)
 		dev->rx_urb_size = dev->hard_mtu;
 	dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
-	
+
 	SET_NETDEV_DEV(net, &udev->dev);
 	status = register_netdev (net);
 	if (status)
@@ -1255,7 +1258,7 @@
 int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
 {
 	struct usbnet		*dev = usb_get_intfdata(intf);
-	
+
 	/* accelerate emptying of the rx and queues, to avoid
 	 * having everything error out.
 	 */
@@ -1286,7 +1289,7 @@
 			< sizeof (struct skb_data));
 
 	random_ether_addr(node_id);
- 	return 0;
+	return 0;
 }
 module_init(usbnet_init);
 
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
index 0af42e3..18816bf 100644
--- a/drivers/usb/serial/airprime.c
+++ b/drivers/usb/serial/airprime.c
@@ -58,11 +58,6 @@
 	if (urb->status) {
 		dbg("%s - nonzero read bulk status received: %d",
 		    __FUNCTION__, urb->status);
-		/* something happened, so free up the memory for this urb */
-		if (urb->transfer_buffer) {
-			kfree (urb->transfer_buffer);
-			urb->transfer_buffer = NULL;
-		}
 		return;
 	}
 	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
@@ -146,6 +141,8 @@
 				  airprime_read_bulk_callback, port);
 		result = usb_submit_urb(urb, GFP_KERNEL);
 		if (result) {
+			usb_free_urb(urb);
+			kfree(buffer);
 			dev_err(&port->dev,
 				"%s - failed submitting read urb %d for port %d, error %d\n",
 				__FUNCTION__, i, port->number, result);
@@ -160,27 +157,12 @@
 	/* some error happened, cancel any submitted urbs and clean up anything that
 	   got allocated successfully */
 
-	for ( ; i >= 0; --i) {
+	while (i-- != 0) {
 		urb = priv->read_urbp[i];
-		if (urb) {
-			/* This urb was submitted successfully. So we have to
-			   cancel it.
-			   Unlinking the urb will invoke read_bulk_callback()
-			   with an error status, so its transfer buffer will
-			   be freed there */
-			if (usb_unlink_urb (urb) != -EINPROGRESS) {
-				/* comments in drivers/usb/core/urb.c say this
-				   can only happen if the urb was never submitted,
-				   or has completed already.
-				   Either way we may have to free the transfer
-				   buffer here. */
-				if (urb->transfer_buffer) {
-					kfree (urb->transfer_buffer);
-					urb->transfer_buffer = NULL;
-				}
-			}
-			usb_free_urb (urb);
-		}
+		buffer = urb->transfer_buffer;
+		usb_kill_urb (urb);
+		usb_free_urb (urb);
+		kfree (buffer);
 	}
 
  out:
@@ -194,10 +176,9 @@
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
-	/* killing the urb will invoke read_bulk_callback() with an error status,
-	   so the transfer buffer will be freed there */
 	for (i = 0; i < NUM_READ_URBS; ++i) {
 		usb_kill_urb (priv->read_urbp[i]);
+		kfree (priv->read_urbp[i]->transfer_buffer);
 		usb_free_urb (priv->read_urbp[i]);
 	}
 
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index 3ec2487..db623e7 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -69,6 +69,7 @@
 	{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
 	{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
 	{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
+	{ USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */
 	{ USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
 	{ USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
 	{ } /* Terminating Entry */
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 601e064..53baeec 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -66,6 +66,8 @@
 	.num_bulk_out =		NUM_DONT_CARE,
 	.num_ports =		1,
 	.shutdown =		usb_serial_generic_shutdown,
+	.throttle =		usb_serial_generic_throttle,
+	.unthrottle =		usb_serial_generic_unthrottle,
 };
 
 static int generic_probe(struct usb_interface *interface,
@@ -115,6 +117,7 @@
 {
 	struct usb_serial *serial = port->serial;
 	int result = 0;
+	unsigned long flags;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -124,7 +127,13 @@
 	if (port->tty)
 		port->tty->low_latency = 1;
 
-	/* if we have a bulk interrupt, start reading from it */
+	/* clear the throttle flags */
+	spin_lock_irqsave(&port->lock, flags);
+	port->throttled = 0;
+	port->throttle_req = 0;
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	/* if we have a bulk endpoint, start reading from it */
 	if (serial->num_bulk_in) {
 		/* Start reading from the device */
 		usb_fill_bulk_urb (port->read_urb, serial->dev,
@@ -253,31 +262,22 @@
 	return (chars);
 }
 
-void usb_serial_generic_read_bulk_callback (struct urb *urb)
+/* Push data to tty layer and resubmit the bulk read URB */
+static void flush_and_resubmit_read_urb (struct usb_serial_port *port)
 {
-	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial = port->serial;
-	struct tty_struct *tty;
-	unsigned char *data = urb->transfer_buffer;
+	struct urb *urb = port->read_urb;
+	struct tty_struct *tty = port->tty;
 	int result;
 
-	dbg("%s - port %d", __FUNCTION__, port->number);
-
-	if (urb->status) {
-		dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
-		return;
-	}
-
-	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
-
-	tty = port->tty;
+	/* Push data to tty */
 	if (tty && urb->actual_length) {
 		tty_buffer_request_room(tty, urb->actual_length);
-		tty_insert_flip_string(tty, data, urb->actual_length);
-	  	tty_flip_buffer_push(tty);
+		tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length);
+	  	tty_flip_buffer_push(tty); /* is this allowed from an URB callback ? */
 	}
 
-	/* Continue trying to always read  */
+	/* Continue reading from device */
 	usb_fill_bulk_urb (port->read_urb, serial->dev,
 			   usb_rcvbulkpipe (serial->dev,
 				   	    port->bulk_in_endpointAddress),
@@ -290,6 +290,40 @@
 	if (result)
 		dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
 }
+
+void usb_serial_generic_read_bulk_callback (struct urb *urb)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+	unsigned char *data = urb->transfer_buffer;
+	int is_throttled;
+	unsigned long flags;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (urb->status) {
+		dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+		return;
+	}
+
+	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
+
+	/* Throttle the device if requested by tty */
+	if (urb->actual_length) {
+		spin_lock_irqsave(&port->lock, flags);
+		is_throttled = port->throttled = port->throttle_req;
+		spin_unlock_irqrestore(&port->lock, flags);
+		if (is_throttled) {
+			/* Let the received data linger in the read URB;
+			 * usb_serial_generic_unthrottle() will pick it
+			 * up later. */
+			dbg("%s - throttling device", __FUNCTION__);
+			return;
+		}
+	}
+
+	/* Handle data and continue reading from device */
+	flush_and_resubmit_read_urb(port);
+}
 EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
 
 void usb_serial_generic_write_bulk_callback (struct urb *urb)
@@ -308,6 +342,38 @@
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
 
+void usb_serial_generic_throttle (struct usb_serial_port *port)
+{
+	unsigned long flags;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	/* Set the throttle request flag. It will be picked up
+	 * by usb_serial_generic_read_bulk_callback(). */
+	spin_lock_irqsave(&port->lock, flags);
+	port->throttle_req = 1;
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+void usb_serial_generic_unthrottle (struct usb_serial_port *port)
+{
+	int was_throttled;
+	unsigned long flags;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	/* Clear the throttle flags */
+	spin_lock_irqsave(&port->lock, flags);
+	was_throttled = port->throttled;
+	port->throttled = port->throttle_req = 0;
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	if (was_throttled) {
+		/* Handle pending data and resume reading from device */
+		flush_and_resubmit_read_urb(port);
+	}
+}
+
 void usb_serial_generic_shutdown (struct usb_serial *serial)
 {
 	int i;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index ced9f32..9963a8b7 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -69,7 +69,6 @@
 /* Vendor and product IDs */
 #define OPTION_VENDOR_ID                0x0AF0
 #define HUAWEI_VENDOR_ID                0x12D1
-#define AUDIOVOX_VENDOR_ID              0x0F3D
 #define NOVATELWIRELESS_VENDOR_ID       0x1410
 #define ANYDATA_VENDOR_ID               0x16d5
 
@@ -81,7 +80,6 @@
 #define OPTION_PRODUCT_GTMAX36          0x6701
 #define HUAWEI_PRODUCT_E600             0x1001
 #define HUAWEI_PRODUCT_E220             0x1003
-#define AUDIOVOX_PRODUCT_AIRCARD        0x0112
 #define NOVATELWIRELESS_PRODUCT_U740    0x1400
 #define ANYDATA_PRODUCT_ID              0x6501
 
@@ -94,7 +92,6 @@
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
 	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
 	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
-	{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
 	{ } /* Terminating entry */
@@ -109,7 +106,6 @@
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
 	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
 	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
-	{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
 	{ } /* Terminating entry */
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 6c083d4..83dfae9 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -83,6 +83,7 @@
 	{ USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
 	{ USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
 	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) },
+	{ USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
 
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index 65a50396..f9a71d0 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -97,3 +97,8 @@
 /* Huawei E620 UMTS/HSDPA card (ID: 12d1:1001) */
 #define HUAWEI_VENDOR_ID	0x12d1
 #define HUAWEI_PRODUCT_ID	0x1001
+
+/* Willcom WS002IN Data Driver (by NetIndex Inc.) */
+#define WS002IN_VENDOR_ID	0x11f6
+#define WS002IN_PRODUCT_ID	0x2001
+
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 70234f5..e227f64 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -153,6 +153,12 @@
 		if (us->flags & US_FL_FIX_CAPACITY)
 			sdev->fix_capacity = 1;
 
+		/* A few disks have two indistinguishable version, one of
+		 * which reports the correct capacity and the other does not.
+		 * The sd driver has to guess which is the case. */
+		if (us->flags & US_FL_CAPACITY_HEURISTICS)
+			sdev->guess_capacity = 1;
+
 		/* Some devices report a SCSI revision level above 2 but are
 		 * unable to handle the REPORT LUNS command (for which
 		 * support is mandatory at level 3).  Since we already have
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index f49a62f..9644a8e 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1101,6 +1101,15 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_SINGLE_LUN),
 
+/* Submitted by Dylan Taft <d13f00l@gmail.com>
+ * US_FL_IGNORE_RESIDUE Needed
+ */
+UNUSUAL_DEV(  0x08ca, 0x3103, 0x0100, 0x0100,
+                "AIPTEK",
+                "Aiptek USB Keychain MP3 Player",
+                US_SC_DEVICE, US_PR_DEVICE, NULL,
+                US_FL_IGNORE_RESIDUE),
+
 /* Entry needed for flags. Moreover, all devices with this ID use
  * bulk-only transport, but _some_ falsely report Control/Bulk instead.
  * One example is "Trumpion Digital Research MYMP3".
@@ -1311,12 +1320,13 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_NO_WP_DETECT ),
 
-/* Reported by Jan Mate <mate@fiit.stuba.sk> */
+/* Reported by Jan Mate <mate@fiit.stuba.sk>
+ * and by Soeren Sonnenburg <kernel@nn7.de> */
 UNUSUAL_DEV(  0x0fce, 0xe030, 0x0000, 0x0000,
 		"Sony Ericsson",
 		"P990i",
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY ),
+		US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ),
 
 /* Reported by Emmanuel Vasilakis <evas@forthnet.gr> */
 UNUSUAL_DEV(  0x0fce, 0xe031, 0x0000, 0x0000,
@@ -1385,6 +1395,16 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
+/* Reported by Thomas Baechler <thomas@archlinux.org>
+ * Fixes I/O errors with Teac HD-35PU devices
+ */
+
+UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201,
+               "Super Top",
+               "USB 2.0  IDE DEVICE",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_IGNORE_RESIDUE),
+
 /* patch submitted by Davide Perini <perini.davide@dpsoftware.org>
  * and Renato Perini <rperini@email.it>
  */
@@ -1423,7 +1443,7 @@
 		"DataStor",
 		"USB4500 FW1.04",
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY),
+		US_FL_CAPACITY_HEURISTICS),
 
 /* Control/Bulk transport for all SubClass values */
 USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index 296b091..46929a1 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -90,14 +90,16 @@
 		goto exit;
 	}
 
-	/* prevent the device from being autosuspended */
-	retval = usb_autopm_get_interface(interface);
-	if (retval)
-		goto exit;
-
 	/* increment our usage count for the device */
 	kref_get(&dev->kref);
 
+	/* prevent the device from being autosuspended */
+	retval = usb_autopm_get_interface(interface);
+	if (retval) {
+		kref_put(&dev->kref, skel_delete);
+		goto exit;
+	}
+
 	/* save our object in the file's private structure */
 	file->private_data = dev;
 
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index a9b6301..9041971 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -136,7 +136,8 @@
 }
 
 /**
- * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and release it
+ * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and
+ * 			release it
  * @dentry: dentry to look for fid in
  *
  * find a fid in the dentry and then clone to a new private fid
diff --git a/fs/9p/mux.c b/fs/9p/mux.c
index 147ceef..c783874 100644
--- a/fs/9p/mux.c
+++ b/fs/9p/mux.c
@@ -256,7 +256,7 @@
 	vpt->muxnum--;
 	if (!vpt->muxnum) {
 		dprintk(DEBUG_MUX, "destroy proc %p\n", vpt);
-		send_sig(SIGKILL, vpt->task, 1);
+		kthread_stop(vpt->task);
 		vpt->task = NULL;
 		v9fs_mux_poll_task_num--;
 	}
@@ -438,11 +438,8 @@
 
 	vpt = a;
 	dprintk(DEBUG_MUX, "start %p %p\n", current, vpt);
-	allow_signal(SIGKILL);
 	while (!kthread_should_stop()) {
 		set_current_state(TASK_INTERRUPTIBLE);
-		if (signal_pending(current))
-			break;
 
 		list_for_each_entry_safe(m, mtmp, &vpt->mux_list, mux_list) {
 			v9fs_poll_mux(m);
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index d9b561b..6ad6f19 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -53,6 +53,8 @@
 	Opt_uname, Opt_remotename,
 	/* Options that take no arguments */
 	Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd,
+	/* Cache options */
+	Opt_cache_loose,
 	/* Error token */
 	Opt_err
 };
@@ -76,6 +78,8 @@
 	{Opt_fd, "fd"},
 	{Opt_legacy, "noextend"},
 	{Opt_nodevmap, "nodevmap"},
+	{Opt_cache_loose, "cache=loose"},
+	{Opt_cache_loose, "loose"},
 	{Opt_err, NULL}
 };
 
@@ -106,6 +110,7 @@
 	v9ses->debug = 0;
 	v9ses->rfdno = ~0;
 	v9ses->wfdno = ~0;
+	v9ses->cache = 0;
 
 	if (!options)
 		return;
@@ -121,7 +126,6 @@
 					"integer field, but no integer?\n");
 				continue;
 			}
-
 		}
 		switch (token) {
 		case Opt_port:
@@ -169,6 +173,9 @@
 		case Opt_nodevmap:
 			v9ses->nodev = 1;
 			break;
+		case Opt_cache_loose:
+			v9ses->cache = CACHE_LOOSE;
+			break;
 		default:
 			continue;
 		}
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index c134d10..820bf5c 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -47,7 +47,7 @@
 	unsigned int afid;	/* authentication fid */
 	unsigned int rfdno;	/* read file descriptor number */
 	unsigned int wfdno;	/* write file descriptor number */
-
+	unsigned int cache;	/* cache mode */
 
 	char *name;		/* user name to mount as */
 	char *remotename;	/* name of remote hierarchy being mounted */
@@ -73,6 +73,13 @@
 	PROTO_FD,
 };
 
+/* possible values of ->cache */
+/* eventually support loose, tight, time, session, default always none */
+enum {
+	CACHE_NONE,		/* default */
+	CACHE_LOOSE,		/* no consistency */
+};
+
 extern struct dentry *v9fs_debugfs_root;
 
 int v9fs_session_init(struct v9fs_session_info *, const char *, char *);
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index 450b0c1..8ada4c5 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -40,8 +40,10 @@
 extern struct file_system_type v9fs_fs_type;
 extern const struct address_space_operations v9fs_addr_operations;
 extern const struct file_operations v9fs_file_operations;
+extern const struct file_operations v9fs_cached_file_operations;
 extern const struct file_operations v9fs_dir_operations;
 extern struct dentry_operations v9fs_dentry_operations;
+extern struct dentry_operations v9fs_cached_dentry_operations;
 
 struct inode *v9fs_get_inode(struct super_block *sb, int mode);
 ino_t v9fs_qid2ino(struct v9fs_qid *qid);
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
index cc24abf..bed48fa 100644
--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -63,6 +63,8 @@
 	int total = 0;
 	int result = 0;
 
+	dprintk(DEBUG_VFS, "\n");
+
 	buffer = kmap(page);
 	do {
 		if (count < rsize)
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
index 062daa6..ddffd8a 100644
--- a/fs/9p/vfs_dentry.c
+++ b/fs/9p/vfs_dentry.c
@@ -53,10 +53,31 @@
 static int v9fs_dentry_delete(struct dentry *dentry)
 {
 	dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
+
 	return 1;
 }
 
 /**
+ * v9fs_cached_dentry_delete - called when dentry refcount equals 0
+ * @dentry:  dentry in question
+ *
+ * Only return 1 if our inode is invalid.  Only non-synthetic files
+ * (ones without mtime == 0) should be calling this function.
+ *
+ */
+
+static int v9fs_cached_dentry_delete(struct dentry *dentry)
+{
+	struct inode *inode = dentry->d_inode;
+	dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
+
+	if(!inode)
+		return 1;
+
+	return 0;
+}
+
+/**
  * v9fs_dentry_release - called when dentry is going to be freed
  * @dentry:  dentry that is being release
  *
@@ -87,6 +108,11 @@
 	}
 }
 
+struct dentry_operations v9fs_cached_dentry_operations = {
+	.d_delete = v9fs_cached_dentry_delete,
+	.d_release = v9fs_dentry_release,
+};
+
 struct dentry_operations v9fs_dentry_operations = {
 	.d_delete = v9fs_dentry_delete,
 	.d_release = v9fs_dentry_release,
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 6c78343..653dfa5 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -79,6 +79,13 @@
 	vfid->filp = file;
 	kfree(fcall);
 
+	if((vfid->qid.version) && (v9ses->cache)) {
+		dprintk(DEBUG_VFS, "cached");
+		/* enable cached file options */
+		if(file->f_op == &v9fs_file_operations)
+			file->f_op = &v9fs_cached_file_operations;
+	}
+
 	return 0;
 
 Clunk_Fid:
@@ -238,6 +245,17 @@
 	return total;
 }
 
+const struct file_operations v9fs_cached_file_operations = {
+	.llseek = generic_file_llseek,
+	.read = do_sync_read,
+	.aio_read = generic_file_aio_read,
+	.write = v9fs_file_write,
+	.open = v9fs_file_open,
+	.release = v9fs_dir_release,
+	.lock = v9fs_file_lock,
+	.mmap = generic_file_mmap,
+};
+
 const struct file_operations v9fs_file_operations = {
 	.llseek = generic_file_llseek,
 	.read = v9fs_file_read,
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 5cf2213..124a085 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -504,7 +504,10 @@
 		goto error;
 	}
 
-	dentry->d_op = &v9fs_dentry_operations;
+	if(v9ses->cache)
+		dentry->d_op = &v9fs_cached_dentry_operations;
+	else
+		dentry->d_op = &v9fs_dentry_operations;
 	d_instantiate(dentry, inode);
 
 	if (nd && nd->flags & LOOKUP_OPEN) {
@@ -589,7 +592,10 @@
 		goto error;
 	}
 
-	dentry->d_op = &v9fs_dentry_operations;
+	if(v9ses->cache)
+		dentry->d_op = &v9fs_cached_dentry_operations;
+	else
+		dentry->d_op = &v9fs_dentry_operations;
 	d_instantiate(dentry, inode);
 	return 0;
 
@@ -626,7 +632,6 @@
 
 	sb = dir->i_sb;
 	v9ses = v9fs_inode2v9ses(dir);
-	dentry->d_op = &v9fs_dentry_operations;
 	dirfid = v9fs_fid_lookup(dentry->d_parent);
 
 	if(IS_ERR(dirfid))
@@ -697,6 +702,10 @@
 
 	fid->qid = fcall->params.rstat.stat.qid;
 	v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb);
+	if((fid->qid.version)&&(v9ses->cache))
+		dentry->d_op = &v9fs_cached_dentry_operations;
+	else
+		dentry->d_op = &v9fs_dentry_operations;
 
 	d_add(dentry, inode);
 	kfree(fcall);
@@ -1184,7 +1193,10 @@
 		goto free_vfid;
 	}
 
-	dentry->d_op = &v9fs_dentry_operations;
+	if(v9ses->cache)
+		dentry->d_op = &v9fs_cached_dentry_operations;
+	else
+		dentry->d_op = &v9fs_dentry_operations;
 	d_instantiate(dentry, inode);
 	return 0;
 
diff --git a/fs/Kconfig b/fs/Kconfig
index a722b5a..3c4886b 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1189,32 +1189,6 @@
 	  To compile the EFS file system support as a module, choose M here: the
 	  module will be called efs.
 
-config JFFS_FS
-	tristate "Journalling Flash File System (JFFS) support"
-	depends on MTD && BLOCK && BROKEN
-	help
-	  JFFS is the Journalling Flash File System developed by Axis
-	  Communications in Sweden, aimed at providing a crash/powerdown-safe
-	  file system for disk-less embedded devices. Further information is
-	  available at (<http://developer.axis.com/software/jffs/>).
-
-	  NOTE: This filesystem is deprecated and is scheduled for removal in
-	  2.6.21.  See Documentation/feature-removal-schedule.txt
-
-config JFFS_FS_VERBOSE
-	int "JFFS debugging verbosity (0 = quiet, 3 = noisy)"
-	depends on JFFS_FS
-	default "0"
-	help
-	  Determines the verbosity level of the JFFS debugging messages.
-
-config JFFS_PROC_FS
-	bool "JFFS stats available in /proc filesystem"
-	depends on JFFS_FS && PROC_FS
-	help
-	  Enabling this option will cause statistics from mounted JFFS file systems
-	  to be made available to the user in the /proc/fs/jffs/ directory.
-
 config JFFS2_FS
 	tristate "Journalling Flash File System v2 (JFFS2) support"
 	select CRC32
diff --git a/fs/Makefile b/fs/Makefile
index b9ffa63f..9edf411 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -94,7 +94,6 @@
 obj-$(CONFIG_NTFS_FS)		+= ntfs/
 obj-$(CONFIG_UFS_FS)		+= ufs/
 obj-$(CONFIG_EFS_FS)		+= efs/
-obj-$(CONFIG_JFFS_FS)		+= jffs/
 obj-$(CONFIG_JFFS2_FS)		+= jffs2/
 obj-$(CONFIG_AFFS_FS)		+= affs/
 obj-$(CONFIG_ROMFS_FS)		+= romfs/
diff --git a/fs/cifs/README b/fs/cifs/README
index 432e515..080c5eb 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -1,5 +1,5 @@
 The CIFS VFS support for Linux supports many advanced network filesystem 
-features such as heirarchical dfs like namespace, hardlinks, locking and more.  
+features such as hierarchical dfs like namespace, hardlinks, locking and more.  
 It was designed to comply with the SNIA CIFS Technical Reference (which 
 supersedes the 1992 X/Open SMB Standard) as well as to perform best practice 
 practical interoperability with Windows 2000, Windows XP, Samba and equivalent 
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index b8e9147..2436410 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2824,10 +2824,10 @@
 
 
 /* security id for everyone */
-const static struct cifs_sid sid_everyone = 
+static const struct cifs_sid sid_everyone =
 		{1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
 /* group users */
-const static struct cifs_sid sid_user = 
+static const struct cifs_sid sid_user =
 		{1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
 
 /* Convert CIFS ACL to POSIX form */
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 8d130cc..682f928 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
+#include <linux/namei.h>
 #include <linux/debugfs.h>
 
 static ssize_t default_read_file(struct file *file, char __user *buf,
@@ -44,6 +45,17 @@
 	.open =		default_open,
 };
 
+static void *debugfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+	nd_set_link(nd, dentry->d_inode->i_private);
+	return NULL;
+}
+
+const struct inode_operations debugfs_link_operations = {
+	.readlink       = generic_readlink,
+	.follow_link    = debugfs_follow_link,
+};
+
 static void debugfs_u8_set(void *data, u64 val)
 {
 	*(u8 *)data = val;
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index c692487..7b324cf 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -25,11 +25,13 @@
 #include <linux/namei.h>
 #include <linux/debugfs.h>
 #include <linux/fsnotify.h>
+#include <linux/string.h>
 
 #define DEBUGFS_MAGIC	0x64626720
 
 /* declared over in file.c */
 extern struct file_operations debugfs_file_operations;
+extern struct inode_operations debugfs_link_operations;
 
 static struct vfsmount *debugfs_mount;
 static int debugfs_mount_count;
@@ -51,6 +53,9 @@
 		case S_IFREG:
 			inode->i_fop = &debugfs_file_operations;
 			break;
+		case S_IFLNK:
+			inode->i_op = &debugfs_link_operations;
+			break;
 		case S_IFDIR:
 			inode->i_op = &simple_dir_inode_operations;
 			inode->i_fop = &simple_dir_operations;
@@ -96,6 +101,12 @@
 	return res;
 }
 
+static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode)
+{
+	mode = (mode & S_IALLUGO) | S_IFLNK;
+	return debugfs_mknod(dir, dentry, mode, 0);
+}
+
 static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode)
 {
 	int res;
@@ -158,10 +169,17 @@
 	mutex_lock(&parent->d_inode->i_mutex);
 	*dentry = lookup_one_len(name, parent, strlen(name));
 	if (!IS_ERR(*dentry)) {
-		if ((mode & S_IFMT) == S_IFDIR)
+		switch (mode & S_IFMT) {
+		case S_IFDIR:
 			error = debugfs_mkdir(parent->d_inode, *dentry, mode);
-		else 
+			break;
+		case S_IFLNK:
+			error = debugfs_link(parent->d_inode, *dentry, mode);
+			break;
+		default:
 			error = debugfs_create(parent->d_inode, *dentry, mode);
+			break;
+		}
 		dput(*dentry);
 	} else
 		error = PTR_ERR(*dentry);
@@ -194,9 +212,7 @@
  * you are responsible here.)  If an error occurs, %NULL will be returned.
  *
  * If debugfs is not enabled in the kernel, the value -%ENODEV will be
- * returned.  It is not wise to check for this value, but rather, check for
- * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
- * code.
+ * returned.
  */
 struct dentry *debugfs_create_file(const char *name, mode_t mode,
 				   struct dentry *parent, void *data,
@@ -246,9 +262,7 @@
  * you are responsible here.)  If an error occurs, %NULL will be returned.
  *
  * If debugfs is not enabled in the kernel, the value -%ENODEV will be
- * returned.  It is not wise to check for this value, but rather, check for
- * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
- * code.
+ * returned.
  */
 struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
 {
@@ -259,6 +273,47 @@
 EXPORT_SYMBOL_GPL(debugfs_create_dir);
 
 /**
+ * debugfs_create_symlink- create a symbolic link in the debugfs filesystem
+ * @name: a pointer to a string containing the name of the symbolic link to
+ *        create.
+ * @parent: a pointer to the parent dentry for this symbolic link.  This
+ *          should be a directory dentry if set.  If this paramater is NULL,
+ *          then the symbolic link will be created in the root of the debugfs
+ *          filesystem.
+ * @target: a pointer to a string containing the path to the target of the
+ *          symbolic link.
+ *
+ * This function creates a symbolic link with the given name in debugfs that
+ * links to the given target path.
+ *
+ * This function will return a pointer to a dentry if it succeeds.  This
+ * pointer must be passed to the debugfs_remove() function when the symbolic
+ * link is to be removed (no automatic cleanup happens if your module is
+ * unloaded, you are responsible here.)  If an error occurs, %NULL will be
+ * returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
+ * returned.
+ */
+struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
+				      const char *target)
+{
+	struct dentry *result;
+	char *link;
+
+	link = kstrdup(target, GFP_KERNEL);
+	if (!link)
+		return NULL;
+
+	result = debugfs_create_file(name, S_IFLNK | S_IRWXUGO, parent, link,
+				     NULL);
+	if (!result)
+		kfree(link);
+	return result;
+}
+EXPORT_SYMBOL_GPL(debugfs_create_symlink);
+
+/**
  * debugfs_remove - removes a file or directory from the debugfs filesystem
  * @dentry: a pointer to a the dentry of the file or directory to be
  *          removed.
@@ -287,15 +342,22 @@
 	if (debugfs_positive(dentry)) {
 		if (dentry->d_inode) {
 			dget(dentry);
-			if (S_ISDIR(dentry->d_inode->i_mode)) {
+			switch (dentry->d_inode->i_mode & S_IFMT) {
+			case S_IFDIR:
 				ret = simple_rmdir(parent->d_inode, dentry);
 				if (ret)
 					printk(KERN_ERR
 						"DebugFS rmdir on %s failed : "
 						"directory not empty.\n",
 						dentry->d_name.name);
-			} else
+				break;
+			case S_IFLNK:
+				kfree(dentry->d_inode->i_private);
+				/* fall through */
+			default:
 				simple_unlink(parent->d_inode, dentry);
+				break;
+			}
 			if (!ret)
 				d_delete(dentry);
 			dput(dentry);
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index dc2724f..7916b50 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -222,7 +222,7 @@
 
 	size = (inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header))
 			/ sizeof(struct ext4_extent);
-#ifdef AGRESSIVE_TEST
+#ifdef AGGRESSIVE_TEST
 	if (size > 6)
 		size = 6;
 #endif
@@ -235,7 +235,7 @@
 
 	size = (inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header))
 			/ sizeof(struct ext4_extent_idx);
-#ifdef AGRESSIVE_TEST
+#ifdef AGGRESSIVE_TEST
 	if (size > 5)
 		size = 5;
 #endif
@@ -249,7 +249,7 @@
 	size = sizeof(EXT4_I(inode)->i_data);
 	size -= sizeof(struct ext4_extent_header);
 	size /= sizeof(struct ext4_extent);
-#ifdef AGRESSIVE_TEST
+#ifdef AGGRESSIVE_TEST
 	if (size > 3)
 		size = 3;
 #endif
@@ -263,7 +263,7 @@
 	size = sizeof(EXT4_I(inode)->i_data);
 	size -= sizeof(struct ext4_extent_header);
 	size /= sizeof(struct ext4_extent_idx);
-#ifdef AGRESSIVE_TEST
+#ifdef AGGRESSIVE_TEST
 	if (size > 4)
 		size = 4;
 #endif
@@ -1118,7 +1118,7 @@
 	 */
 	if (le16_to_cpu(ex1->ee_len) + le16_to_cpu(ex2->ee_len) > EXT_MAX_LEN)
 		return 0;
-#ifdef AGRESSIVE_TEST
+#ifdef AGGRESSIVE_TEST
 	if (le16_to_cpu(ex1->ee_len) >= 4)
 		return 0;
 #endif
@@ -1891,8 +1891,8 @@
 
 	if (test_opt(sb, EXTENTS)) {
 		printk("EXT4-fs: file extents enabled");
-#ifdef AGRESSIVE_TEST
-		printk(", agressive tests");
+#ifdef AGGRESSIVE_TEST
+		printk(", aggressive tests");
 #endif
 #ifdef CHECK_BINSEARCH
 		printk(", check binsearch");
diff --git a/fs/jffs/Makefile b/fs/jffs/Makefile
deleted file mode 100644
index 9c1c0bb..0000000
--- a/fs/jffs/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for the linux Journalling Flash FileSystem (JFFS) routines.
-#
-# $Id: Makefile,v 1.11 2001/09/25 20:59:41 dwmw2 Exp $
-#
-
-obj-$(CONFIG_JFFS_FS) += jffs.o
-
-jffs-y 				:= jffs_fm.o intrep.o inode-v23.o
-jffs-$(CONFIG_JFFS_PROC_FS)	+= jffs_proc.o
-jffs-objs			:= $(jffs-y)
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
deleted file mode 100644
index 9602b92..0000000
--- a/fs/jffs/inode-v23.c
+++ /dev/null
@@ -1,1847 +0,0 @@
-/*
- * JFFS -- Journalling Flash File System, Linux implementation.
- *
- * Copyright (C) 1999, 2000  Axis Communications AB.
- *
- * Created by Finn Hakansson <finn@axis.com>.
- *
- * This 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.
- *
- * $Id: inode-v23.c,v 1.70 2001/10/02 09:16:02 dwmw2 Exp $
- *
- * Ported to Linux 2.3.x and MTD:
- * Copyright (C) 2000  Alexander Larsson (alex@cendio.se), Cendio Systems AB
- *
- * Copyright 2000, 2001  Red Hat, Inc.
- */
-
-/* inode.c -- Contains the code that is called from the VFS.  */
-
-/* TODO-ALEX:
- * uid and gid are just 16 bit.
- * jffs_file_write reads from user-space pointers without xx_from_user
- * maybe other stuff do to.
- */
-
-#include <linux/time.h>
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/jffs.h>
-#include <linux/fs.h>
-#include <linux/smp_lock.h>
-#include <linux/ioctl.h>
-#include <linux/stat.h>
-#include <linux/blkdev.h>
-#include <linux/quotaops.h>
-#include <linux/highmem.h>
-#include <linux/vfs.h>
-#include <linux/mutex.h>
-#include <asm/byteorder.h>
-#include <asm/uaccess.h>
-
-#include "jffs_fm.h"
-#include "intrep.h"
-#ifdef CONFIG_JFFS_PROC_FS
-#include "jffs_proc.h"
-#endif
-
-static int jffs_remove(struct inode *dir, struct dentry *dentry, int type);
-
-static const struct super_operations jffs_ops;
-static const struct file_operations jffs_file_operations;
-static const struct inode_operations jffs_file_inode_operations;
-static const struct file_operations jffs_dir_operations;
-static const struct inode_operations jffs_dir_inode_operations;
-static const struct address_space_operations jffs_address_operations;
-
-struct kmem_cache     *node_cache = NULL;
-struct kmem_cache     *fm_cache = NULL;
-
-/* Called by the VFS at mount time to initialize the whole file system.  */
-static int jffs_fill_super(struct super_block *sb, void *data, int silent)
-{
-	struct inode *root_inode;
-	struct jffs_control *c;
-
-	sb->s_flags |= MS_NODIRATIME;
-
-	D1(printk(KERN_NOTICE "JFFS: Trying to mount device %s.\n",
-		  sb->s_id));
-
-	if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR) {
-		printk(KERN_WARNING "JFFS: Trying to mount a "
-		       "non-mtd device.\n");
-		return -EINVAL;
-	}
-
-	sb->s_blocksize = PAGE_CACHE_SIZE;
-	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-	sb->s_fs_info = (void *) 0;
-	sb->s_maxbytes = 0xFFFFFFFF;
-
-	/* Build the file system.  */
-	if (jffs_build_fs(sb) < 0) {
-		goto jffs_sb_err1;
-	}
-
-	/*
-	 * set up enough so that we can read an inode
-	 */
-	sb->s_magic = JFFS_MAGIC_SB_BITMASK;
-	sb->s_op = &jffs_ops;
-
-	root_inode = iget(sb, JFFS_MIN_INO);
-	if (!root_inode)
-	        goto jffs_sb_err2;
-
-	/* Get the root directory of this file system.  */
-	if (!(sb->s_root = d_alloc_root(root_inode))) {
-		goto jffs_sb_err3;
-	}
-
-	c = (struct jffs_control *) sb->s_fs_info;
-
-#ifdef CONFIG_JFFS_PROC_FS
-	/* Set up the jffs proc file system.  */
-	if (jffs_register_jffs_proc_dir(MINOR(sb->s_dev), c) < 0) {
-		printk(KERN_WARNING "JFFS: Failed to initialize the JFFS "
-			"proc file system for device %s.\n",
-			sb->s_id);
-	}
-#endif
-
-	/* Set the Garbage Collection thresholds */
-
-	/* GC if free space goes below 5% of the total size */
-	c->gc_minfree_threshold = c->fmc->flash_size / 20;
-
-	if (c->gc_minfree_threshold < c->fmc->sector_size)
-		c->gc_minfree_threshold = c->fmc->sector_size;
-
-	/* GC if dirty space exceeds 33% of the total size. */
-	c->gc_maxdirty_threshold = c->fmc->flash_size / 3;
-
-	if (c->gc_maxdirty_threshold < c->fmc->sector_size)
-		c->gc_maxdirty_threshold = c->fmc->sector_size;
-
-
-	c->thread_pid = kernel_thread (jffs_garbage_collect_thread, 
-				        (void *) c, 
-				        CLONE_KERNEL);
-	D1(printk(KERN_NOTICE "JFFS: GC thread pid=%d.\n", (int) c->thread_pid));
-
-	D1(printk(KERN_NOTICE "JFFS: Successfully mounted device %s.\n",
-	       sb->s_id));
-	return 0;
-
-jffs_sb_err3:
-	iput(root_inode);
-jffs_sb_err2:
-	jffs_cleanup_control((struct jffs_control *)sb->s_fs_info);
-jffs_sb_err1:
-	printk(KERN_WARNING "JFFS: Failed to mount device %s.\n",
-	       sb->s_id);
-	return -EINVAL;
-}
-
-
-/* This function is called when the file system is umounted.  */
-static void
-jffs_put_super(struct super_block *sb)
-{
-	struct jffs_control *c = (struct jffs_control *) sb->s_fs_info;
-
-	D2(printk("jffs_put_super()\n"));
-
-#ifdef CONFIG_JFFS_PROC_FS
-	jffs_unregister_jffs_proc_dir(c);
-#endif
-
-	if (c->gc_task) {
-		D1(printk (KERN_NOTICE "jffs_put_super(): Telling gc thread to die.\n"));
-		send_sig(SIGKILL, c->gc_task, 1);
-	}
-	wait_for_completion(&c->gc_thread_comp);
-
-	D1(printk (KERN_NOTICE "jffs_put_super(): Successfully waited on thread.\n"));
-
-	jffs_cleanup_control((struct jffs_control *)sb->s_fs_info);
-	D1(printk(KERN_NOTICE "JFFS: Successfully unmounted device %s.\n",
-	       sb->s_id));
-}
-
-
-/* This function is called when user commands like chmod, chgrp and
-   chown are executed. System calls like trunc() results in a call
-   to this function.  */
-static int
-jffs_setattr(struct dentry *dentry, struct iattr *iattr)
-{
-	struct inode *inode = dentry->d_inode;
-	struct jffs_raw_inode raw_inode;
-	struct jffs_control *c;
-	struct jffs_fmcontrol *fmc;
-	struct jffs_file *f;
-	struct jffs_node *new_node;
-	int update_all;
-	int res = 0;
-	int recoverable = 0;
-
-	lock_kernel();
-
-	if ((res = inode_change_ok(inode, iattr))) 
-		goto out;
-
-	c = (struct jffs_control *)inode->i_sb->s_fs_info;
-	fmc = c->fmc;
-
-	D3(printk (KERN_NOTICE "notify_change(): down biglock\n"));
-	mutex_lock(&fmc->biglock);
-
-	f = jffs_find_file(c, inode->i_ino);
-
-	ASSERT(if (!f) {
-		printk("jffs_setattr(): Invalid inode number: %lu\n",
-		       inode->i_ino);
-		D3(printk (KERN_NOTICE "notify_change(): up biglock\n"));
-		mutex_unlock(&fmc->biglock);
-		res = -EINVAL;
-		goto out;
-	});
-
-	D1(printk("***jffs_setattr(): file: \"%s\", ino: %u\n",
-		  f->name, f->ino));
-
-	update_all = iattr->ia_valid & ATTR_FORCE;
-
-	if ( (update_all || iattr->ia_valid & ATTR_SIZE)
-	     && (iattr->ia_size + 128 < f->size) ) {
-		/* We're shrinking the file by more than 128 bytes.
-		   We'll be able to GC and recover this space, so
-		   allow it to go into the reserved space. */
-		recoverable = 1;
-        }
-
-	if (!(new_node = jffs_alloc_node())) {
-		D(printk("jffs_setattr(): Allocation failed!\n"));
-		D3(printk (KERN_NOTICE "notify_change(): up biglock\n"));
-		mutex_unlock(&fmc->biglock);
-		res = -ENOMEM;
-		goto out;
-	}
-
-	new_node->data_offset = 0;
-	new_node->removed_size = 0;
-	raw_inode.magic = JFFS_MAGIC_BITMASK;
-	raw_inode.ino = f->ino;
-	raw_inode.pino = f->pino;
-	raw_inode.mode = f->mode;
-	raw_inode.uid = f->uid;
-	raw_inode.gid = f->gid;
-	raw_inode.atime = f->atime;
-	raw_inode.mtime = f->mtime;
-	raw_inode.ctime = f->ctime;
-	raw_inode.dsize = 0;
-	raw_inode.offset = 0;
-	raw_inode.rsize = 0;
-	raw_inode.dsize = 0;
-	raw_inode.nsize = f->nsize;
-	raw_inode.nlink = f->nlink;
-	raw_inode.spare = 0;
-	raw_inode.rename = 0;
-	raw_inode.deleted = 0;
-
-	if (update_all || iattr->ia_valid & ATTR_MODE) {
-		raw_inode.mode = iattr->ia_mode;
-		inode->i_mode = iattr->ia_mode;
-	}
-	if (update_all || iattr->ia_valid & ATTR_UID) {
-		raw_inode.uid = iattr->ia_uid;
-		inode->i_uid = iattr->ia_uid;
-	}
-	if (update_all || iattr->ia_valid & ATTR_GID) {
-		raw_inode.gid = iattr->ia_gid;
-		inode->i_gid = iattr->ia_gid;
-	}
-	if (update_all || iattr->ia_valid & ATTR_SIZE) {
-		int len;
-		D1(printk("jffs_notify_change(): Changing size "
-			  "to %lu bytes!\n", (long)iattr->ia_size));
-		raw_inode.offset = iattr->ia_size;
-
-		/* Calculate how many bytes need to be removed from
-		   the end.  */
-		if (f->size < iattr->ia_size) {
-			len = 0;
-		}
-		else {
-			len = f->size - iattr->ia_size;
-		}
-
-		raw_inode.rsize = len;
-
-		/* The updated node will be a removal node, with
-		   base at the new size and size of the nbr of bytes
-		   to be removed.  */
-		new_node->data_offset = iattr->ia_size;
-		new_node->removed_size = len;
-		inode->i_size = iattr->ia_size;
-		inode->i_blocks = (inode->i_size + 511) >> 9;
-
-		if (len) {
-			invalidate_mapping_pages(inode->i_mapping, 0, -1);
-		}
-		inode->i_ctime = CURRENT_TIME_SEC;
-		inode->i_mtime = inode->i_ctime;
-	}
-	if (update_all || iattr->ia_valid & ATTR_ATIME) {
-		raw_inode.atime = iattr->ia_atime.tv_sec;
-		inode->i_atime = iattr->ia_atime;
-	}
-	if (update_all || iattr->ia_valid & ATTR_MTIME) {
-		raw_inode.mtime = iattr->ia_mtime.tv_sec;
-		inode->i_mtime = iattr->ia_mtime;
-	}
-	if (update_all || iattr->ia_valid & ATTR_CTIME) {
-		raw_inode.ctime = iattr->ia_ctime.tv_sec;
-		inode->i_ctime = iattr->ia_ctime;
-	}
-
-	/* Write this node to the flash.  */
-	if ((res = jffs_write_node(c, new_node, &raw_inode, f->name, NULL, recoverable, f)) < 0) {
-		D(printk("jffs_notify_change(): The write failed!\n"));
-		jffs_free_node(new_node);
-		D3(printk (KERN_NOTICE "n_c(): up biglock\n"));
-		mutex_unlock(&c->fmc->biglock);
-		goto out;
-	}
-
-	jffs_insert_node(c, f, &raw_inode, NULL, new_node);
-
-	mark_inode_dirty(inode);
-	D3(printk (KERN_NOTICE "n_c(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-out:
-	unlock_kernel();
-	return res;
-} /* jffs_notify_change()  */
-
-
-static struct inode *
-jffs_new_inode(const struct inode * dir, struct jffs_raw_inode *raw_inode,
-	       int * err)
-{
-	struct super_block * sb;
-	struct inode * inode;
-	struct jffs_control *c;
-	struct jffs_file *f;
-
-	sb = dir->i_sb;
-	inode = new_inode(sb);
-	if (!inode) {
-		*err = -ENOMEM;
-		return NULL;
-	}
-
-	c = (struct jffs_control *)sb->s_fs_info;
-
-	inode->i_ino = raw_inode->ino;
-	inode->i_mode = raw_inode->mode;
-	inode->i_nlink = raw_inode->nlink;
-	inode->i_uid = raw_inode->uid;
-	inode->i_gid = raw_inode->gid;
-	inode->i_size = raw_inode->dsize;
-	inode->i_atime.tv_sec = raw_inode->atime;
-	inode->i_mtime.tv_sec = raw_inode->mtime;
-	inode->i_ctime.tv_sec = raw_inode->ctime;
-	inode->i_ctime.tv_nsec = 0;
-	inode->i_mtime.tv_nsec = 0;
-	inode->i_atime.tv_nsec = 0;
-	inode->i_blocks = (inode->i_size + 511) >> 9;
-
-	f = jffs_find_file(c, raw_inode->ino);
-
-	inode->i_private = (void *)f;
-	insert_inode_hash(inode);
-
-	return inode;
-}
-
-/* Get statistics of the file system.  */
-static int
-jffs_statfs(struct dentry *dentry, struct kstatfs *buf)
-{
-	struct jffs_control *c = (struct jffs_control *) dentry->d_sb->s_fs_info;
-	struct jffs_fmcontrol *fmc;
-
-	lock_kernel();
-
-	fmc = c->fmc;
-
-	D2(printk("jffs_statfs()\n"));
-
-	buf->f_type = JFFS_MAGIC_SB_BITMASK;
-	buf->f_bsize = PAGE_CACHE_SIZE;
-	buf->f_blocks = (fmc->flash_size / PAGE_CACHE_SIZE)
-		       - (fmc->min_free_size / PAGE_CACHE_SIZE);
-	buf->f_bfree = (jffs_free_size1(fmc) + jffs_free_size2(fmc) +
-		       fmc->dirty_size - fmc->min_free_size)
-			       >> PAGE_CACHE_SHIFT;
-	buf->f_bavail = buf->f_bfree;
-
-	/* Find out how many files there are in the filesystem.  */
-	buf->f_files = jffs_foreach_file(c, jffs_file_count);
-	buf->f_ffree = buf->f_bfree;
-	/* buf->f_fsid = 0; */
-	buf->f_namelen = JFFS_MAX_NAME_LEN;
-
-	unlock_kernel();
-
-	return 0;
-}
-
-
-/* Rename a file.  */
-static int
-jffs_rename(struct inode *old_dir, struct dentry *old_dentry,
-	    struct inode *new_dir, struct dentry *new_dentry)
-{
-	struct jffs_raw_inode raw_inode;
-	struct jffs_control *c;
-	struct jffs_file *old_dir_f;
-	struct jffs_file *new_dir_f;
-	struct jffs_file *del_f;
-	struct jffs_file *f;
-	struct jffs_node *node;
-	struct inode *inode;
-	int result = 0;
-	__u32 rename_data = 0;
-
-	D2(printk("***jffs_rename()\n"));
-
-	D(printk("jffs_rename(): old_dir: 0x%p, old name: 0x%p, "
-		 "new_dir: 0x%p, new name: 0x%p\n",
-		 old_dir, old_dentry->d_name.name,
-		 new_dir, new_dentry->d_name.name));
-
-	lock_kernel();
-	c = (struct jffs_control *)old_dir->i_sb->s_fs_info;
-	ASSERT(if (!c) {
-		printk(KERN_ERR "jffs_rename(): The old_dir inode "
-		       "didn't have a reference to a jffs_file struct\n");
-		unlock_kernel();
-		return -EIO;
-	});
-
-	result = -ENOTDIR;
-	if (!(old_dir_f = old_dir->i_private)) {
-		D(printk("jffs_rename(): Old dir invalid.\n"));
-		goto jffs_rename_end;
-	}
-
-	/* Try to find the file to move.  */
-	result = -ENOENT;
-	if (!(f = jffs_find_child(old_dir_f, old_dentry->d_name.name,
-				  old_dentry->d_name.len))) {
-		goto jffs_rename_end;
-	}
-
-	/* Find the new directory.  */
-	result = -ENOTDIR;
-	if (!(new_dir_f = new_dir->i_private)) {
-		D(printk("jffs_rename(): New dir invalid.\n"));
-		goto jffs_rename_end;
-	}
-	D3(printk (KERN_NOTICE "rename(): down biglock\n"));
-	mutex_lock(&c->fmc->biglock);
-	/* Create a node and initialize as much as needed.  */
-	result = -ENOMEM;
-	if (!(node = jffs_alloc_node())) {
-		D(printk("jffs_rename(): Allocation failed: node == 0\n"));
-		goto jffs_rename_end;
-	}
-	node->data_offset = 0;
-	node->removed_size = 0;
-
-	/* Initialize the raw inode.  */
-	raw_inode.magic = JFFS_MAGIC_BITMASK;
-	raw_inode.ino = f->ino;
-	raw_inode.pino = new_dir_f->ino;
-/*  	raw_inode.version = f->highest_version + 1; */
-	raw_inode.mode = f->mode;
-	raw_inode.uid = current->fsuid;
-	raw_inode.gid = current->fsgid;
-#if 0
-	raw_inode.uid = f->uid;
-	raw_inode.gid = f->gid;
-#endif
-	raw_inode.atime = get_seconds();
-	raw_inode.mtime = raw_inode.atime;
-	raw_inode.ctime = f->ctime;
-	raw_inode.offset = 0;
-	raw_inode.dsize = 0;
-	raw_inode.rsize = 0;
-	raw_inode.nsize = new_dentry->d_name.len;
-	raw_inode.nlink = f->nlink;
-	raw_inode.spare = 0;
-	raw_inode.rename = 0;
-	raw_inode.deleted = 0;
-
-	/* See if there already exists a file with the same name as
-	   new_name.  */
-	if ((del_f = jffs_find_child(new_dir_f, new_dentry->d_name.name,
-				     new_dentry->d_name.len))) {
-		raw_inode.rename = 1;
-		raw_inode.dsize = sizeof(__u32);
-		rename_data = del_f->ino;
-	}
-
-	/* Write the new node to the flash memory.  */
-	if ((result = jffs_write_node(c, node, &raw_inode,
-				      new_dentry->d_name.name,
-				      (unsigned char*)&rename_data, 0, f)) < 0) {
-		D(printk("jffs_rename(): Failed to write node to flash.\n"));
-		jffs_free_node(node);
-		goto jffs_rename_end;
-	}
-	raw_inode.dsize = 0;
-
-	if (raw_inode.rename) {
-		/* The file with the same name must be deleted.  */
-		//FIXME deadlock	        down(&c->fmc->gclock);
-		if ((result = jffs_remove(new_dir, new_dentry,
-					  del_f->mode)) < 0) {
-			/* This is really bad.  */
-			printk(KERN_ERR "JFFS: An error occurred in "
-			       "rename().\n");
-		}
-		//		up(&c->fmc->gclock);
-	}
-
-	if (old_dir_f != new_dir_f) {
-		/* Remove the file from its old position in the
-		   filesystem tree.  */
-		jffs_unlink_file_from_tree(f);
-	}
-
-	/* Insert the new node into the file system.  */
-	if ((result = jffs_insert_node(c, f, &raw_inode,
-				       new_dentry->d_name.name, node)) < 0) {
-		D(printk(KERN_ERR "jffs_rename(): jffs_insert_node() "
-			 "failed!\n"));
-	}
-
-	if (old_dir_f != new_dir_f) {
-		/* Insert the file to its new position in the
-		   file system.  */
-		jffs_insert_file_into_tree(f);
-	}
-
-	/* This is a kind of update of the inode we're about to make
-	   here.  This is what they do in ext2fs.  Kind of.  */
-	if ((inode = iget(new_dir->i_sb, f->ino))) {
-		inode->i_ctime = CURRENT_TIME_SEC;
-		mark_inode_dirty(inode);
-		iput(inode);
-	}
-
-jffs_rename_end:
-	D3(printk (KERN_NOTICE "rename(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-	unlock_kernel();
-	return result;
-} /* jffs_rename()  */
-
-
-/* Read the contents of a directory.  Used by programs like `ls'
-   for instance.  */
-static int
-jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
-{
-	struct jffs_file *f;
-	struct dentry *dentry = filp->f_path.dentry;
-	struct inode *inode = dentry->d_inode;
-	struct jffs_control *c = (struct jffs_control *)inode->i_sb->s_fs_info;
-	int j;
-	int ddino;
-	lock_kernel();
-	D3(printk (KERN_NOTICE "readdir(): down biglock\n"));
-	mutex_lock(&c->fmc->biglock);
-
-	D2(printk("jffs_readdir(): inode: 0x%p, filp: 0x%p\n", inode, filp));
-	if (filp->f_pos == 0) {
-		D3(printk("jffs_readdir(): \".\" %lu\n", inode->i_ino));
-		if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0) {
-			D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
-			mutex_unlock(&c->fmc->biglock);
-			unlock_kernel();
-			return 0;
-		}
-		filp->f_pos = 1;
-	}
-	if (filp->f_pos == 1) {
-		if (inode->i_ino == JFFS_MIN_INO) {
-			ddino = JFFS_MIN_INO;
-		}
-		else {
-			ddino = ((struct jffs_file *)
-				 inode->i_private)->pino;
-		}
-		D3(printk("jffs_readdir(): \"..\" %u\n", ddino));
-		if (filldir(dirent, "..", 2, filp->f_pos, ddino, DT_DIR) < 0) {
-			D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
-			mutex_unlock(&c->fmc->biglock);
-			unlock_kernel();
-			return 0;
-		}
-		filp->f_pos++;
-	}
-	f = ((struct jffs_file *)inode->i_private)->children;
-
-	j = 2;
-	while(f && (f->deleted || j++ < filp->f_pos )) {
-		f = f->sibling_next;
-	}
-
-	while (f) {
-		D3(printk("jffs_readdir(): \"%s\" ino: %u\n",
-			  (f->name ? f->name : ""), f->ino));
-		if (filldir(dirent, f->name, f->nsize,
-			    filp->f_pos , f->ino, DT_UNKNOWN) < 0) {
-		        D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
-			mutex_unlock(&c->fmc->biglock);
-			unlock_kernel();
-			return 0;
-		}
-		filp->f_pos++;
-		do {
-			f = f->sibling_next;
-		} while(f && f->deleted);
-	}
-	D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-	unlock_kernel();
-	return filp->f_pos;
-} /* jffs_readdir()  */
-
-
-/* Find a file in a directory. If the file exists, return its
-   corresponding dentry.  */
-static struct dentry *
-jffs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
-{
-	struct jffs_file *d;
-	struct jffs_file *f;
-	struct jffs_control *c = (struct jffs_control *)dir->i_sb->s_fs_info;
-	int len;
-	int r = 0;
-	const char *name;
-	struct inode *inode = NULL;
-
-	len = dentry->d_name.len;
-	name = dentry->d_name.name;
-
-	lock_kernel();
-
-	D3({
-		char *s = kmalloc(len + 1, GFP_KERNEL);
-		memcpy(s, name, len);
-		s[len] = '\0';
-		printk("jffs_lookup(): dir: 0x%p, name: \"%s\"\n", dir, s);
-		kfree(s);
-	});
-
-	D3(printk (KERN_NOTICE "lookup(): down biglock\n"));
-	mutex_lock(&c->fmc->biglock);
-
-	r = -ENAMETOOLONG;
-	if (len > JFFS_MAX_NAME_LEN) {
-		goto jffs_lookup_end;
-	}
-
-	r = -EACCES;
-	if (!(d = (struct jffs_file *)dir->i_private)) {
-		D(printk("jffs_lookup(): No such inode! (%lu)\n",
-			 dir->i_ino));
-		goto jffs_lookup_end;
-	}
-
-	/* Get the corresponding inode to the file.  */
-
-	/* iget calls jffs_read_inode, so we need to drop the biglock
-           before calling iget.  Unfortunately, the GC has a tendency
-           to sneak in here, because iget sometimes calls schedule ().
-	*/
-
-	if ((len == 1) && (name[0] == '.')) {
-		D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
-		mutex_unlock(&c->fmc->biglock);
-		if (!(inode = iget(dir->i_sb, d->ino))) {
-			D(printk("jffs_lookup(): . iget() ==> NULL\n"));
-			goto jffs_lookup_end_no_biglock;
-		}
-		D3(printk (KERN_NOTICE "lookup(): down biglock\n"));
-		mutex_lock(&c->fmc->biglock);
-	} else if ((len == 2) && (name[0] == '.') && (name[1] == '.')) {
-	        D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
-		mutex_unlock(&c->fmc->biglock);
- 		if (!(inode = iget(dir->i_sb, d->pino))) {
-			D(printk("jffs_lookup(): .. iget() ==> NULL\n"));
-			goto jffs_lookup_end_no_biglock;
-		}
-		D3(printk (KERN_NOTICE "lookup(): down biglock\n"));
-		mutex_lock(&c->fmc->biglock);
-	} else if ((f = jffs_find_child(d, name, len))) {
-	        D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
-		mutex_unlock(&c->fmc->biglock);
-		if (!(inode = iget(dir->i_sb, f->ino))) {
-			D(printk("jffs_lookup(): iget() ==> NULL\n"));
-			goto jffs_lookup_end_no_biglock;
-		}
-		D3(printk (KERN_NOTICE "lookup(): down biglock\n"));
-		mutex_lock(&c->fmc->biglock);
-	} else {
-		D3(printk("jffs_lookup(): Couldn't find the file. "
-			  "f = 0x%p, name = \"%s\", d = 0x%p, d->ino = %u\n",
-			  f, name, d, d->ino));
-		inode = NULL;
-	}
-
-	d_add(dentry, inode);
-	D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-	unlock_kernel();
-	return NULL;
-
-jffs_lookup_end:
-	D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-
-jffs_lookup_end_no_biglock:
-	unlock_kernel();
-	return ERR_PTR(r);
-} /* jffs_lookup()  */
-
-
-/* Try to read a page of data from a file.  */
-static int
-jffs_do_readpage_nolock(struct file *file, struct page *page)
-{
-	void *buf;
-	unsigned long read_len;
-	int result;
-	struct inode *inode = (struct inode*)page->mapping->host;
-	struct jffs_file *f = (struct jffs_file *)inode->i_private;
-	struct jffs_control *c = (struct jffs_control *)inode->i_sb->s_fs_info;
-	int r;
-	loff_t offset;
-
-	D2(printk("***jffs_readpage(): file = \"%s\", page->index = %lu\n",
-		  (f->name ? f->name : ""), (long)page->index));
-
-	get_page(page);
-	/* Don't SetPageLocked(page), should be locked already */
-	ClearPageUptodate(page);
-	ClearPageError(page);
-
-	D3(printk (KERN_NOTICE "readpage(): down biglock\n"));
-	mutex_lock(&c->fmc->biglock);
-
-	read_len = 0;
-	result = 0;
-	offset = page_offset(page);
-
-	kmap(page);
-	buf = page_address(page);
-	if (offset < inode->i_size) {
-		read_len = min_t(long, inode->i_size - offset, PAGE_SIZE);
-		r = jffs_read_data(f, buf, offset, read_len);
-		if (r != read_len) {
-			result = -EIO;
-			D(
-			        printk("***jffs_readpage(): Read error! "
-				       "Wanted to read %lu bytes but only "
-				       "read %d bytes.\n", read_len, r);
-			  );
-		}
-
-	}
-
-	/* This handles the case of partial or no read in above */
-	if(read_len < PAGE_SIZE)
-	        memset(buf + read_len, 0, PAGE_SIZE - read_len);
-	flush_dcache_page(page);
-	kunmap(page);
-
-	D3(printk (KERN_NOTICE "readpage(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-
-	if (result) {
-	        SetPageError(page);
-	}else {
-	        SetPageUptodate(page);	        
-	}
-
-	page_cache_release(page);
-
-	D3(printk("jffs_readpage(): Leaving...\n"));
-
-	return result;
-} /* jffs_do_readpage_nolock()  */
-
-static int jffs_readpage(struct file *file, struct page *page)
-{
-	int ret = jffs_do_readpage_nolock(file, page);
-	unlock_page(page);
-	return ret;
-}
-
-/* Create a new directory.  */
-static int
-jffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
-{
-	struct jffs_raw_inode raw_inode;
-	struct jffs_control *c;
-	struct jffs_node *node;
-	struct jffs_file *dir_f;
-	struct inode *inode;
-	int dir_mode;
-	int result = 0;
-	int err;
-
-	D1({
-	        int len = dentry->d_name.len;
-		char *_name = kmalloc(len + 1, GFP_KERNEL);
-		memcpy(_name, dentry->d_name.name, len);
-		_name[len] = '\0';
-		printk("***jffs_mkdir(): dir = 0x%p, name = \"%s\", "
-		       "len = %d, mode = 0x%08x\n", dir, _name, len, mode);
-		kfree(_name);
-	});
-
-	lock_kernel();
-	dir_f = dir->i_private;
-
-	ASSERT(if (!dir_f) {
-		printk(KERN_ERR "jffs_mkdir(): No reference to a "
-		       "jffs_file struct in inode.\n");
-		unlock_kernel();
-		return -EIO;
-	});
-
-	c = dir_f->c;
-	D3(printk (KERN_NOTICE "mkdir(): down biglock\n"));
-	mutex_lock(&c->fmc->biglock);
-
-	dir_mode = S_IFDIR | (mode & (S_IRWXUGO|S_ISVTX)
-			      & ~current->fs->umask);
-	if (dir->i_mode & S_ISGID) {
-		dir_mode |= S_ISGID;
-	}
-
-	/* Create a node and initialize it as much as needed.  */
-	if (!(node = jffs_alloc_node())) {
-		D(printk("jffs_mkdir(): Allocation failed: node == 0\n"));
-		result = -ENOMEM;
-		goto jffs_mkdir_end;
-	}
-	node->data_offset = 0;
-	node->removed_size = 0;
-
-	/* Initialize the raw inode.  */
-	raw_inode.magic = JFFS_MAGIC_BITMASK;
-	raw_inode.ino = c->next_ino++;
-	raw_inode.pino = dir_f->ino;
-	raw_inode.version = 1;
-	raw_inode.mode = dir_mode;
-	raw_inode.uid = current->fsuid;
-	raw_inode.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-	/*	raw_inode.gid = current->fsgid; */
-	raw_inode.atime = get_seconds();
-	raw_inode.mtime = raw_inode.atime;
-	raw_inode.ctime = raw_inode.atime;
-	raw_inode.offset = 0;
-	raw_inode.dsize = 0;
-	raw_inode.rsize = 0;
-	raw_inode.nsize = dentry->d_name.len;
-	raw_inode.nlink = 1;
-	raw_inode.spare = 0;
-	raw_inode.rename = 0;
-	raw_inode.deleted = 0;
-
-	/* Write the new node to the flash.  */
-	if ((result = jffs_write_node(c, node, &raw_inode,
-				     dentry->d_name.name, NULL, 0, NULL)) < 0) {
-		D(printk("jffs_mkdir(): jffs_write_node() failed.\n"));
-		jffs_free_node(node);
-		goto jffs_mkdir_end;
-	}
-
-	/* Insert the new node into the file system.  */
-	if ((result = jffs_insert_node(c, NULL, &raw_inode, dentry->d_name.name,
-				       node)) < 0) {
-		goto jffs_mkdir_end;
-	}
-
-	inode = jffs_new_inode(dir, &raw_inode, &err);
-	if (inode == NULL) {
-		result = err;
-		goto jffs_mkdir_end;
-	}
-
-	inode->i_op = &jffs_dir_inode_operations;
-	inode->i_fop = &jffs_dir_operations;
-
-	mark_inode_dirty(dir);
-	d_instantiate(dentry, inode);
-
-	result = 0;
-jffs_mkdir_end:
-	D3(printk (KERN_NOTICE "mkdir(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-	unlock_kernel();
-	return result;
-} /* jffs_mkdir()  */
-
-
-/* Remove a directory.  */
-static int
-jffs_rmdir(struct inode *dir, struct dentry *dentry)
-{
-	struct jffs_control *c = (struct jffs_control *)dir->i_sb->s_fs_info;
-	int ret;
-	D3(printk("***jffs_rmdir()\n"));
-	D3(printk (KERN_NOTICE "rmdir(): down biglock\n"));
-	lock_kernel();
-	mutex_lock(&c->fmc->biglock);
-	ret = jffs_remove(dir, dentry, S_IFDIR);
-	D3(printk (KERN_NOTICE "rmdir(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-	unlock_kernel();
-	return ret;
-}
-
-
-/* Remove any kind of file except for directories.  */
-static int
-jffs_unlink(struct inode *dir, struct dentry *dentry)
-{
-	struct jffs_control *c = (struct jffs_control *)dir->i_sb->s_fs_info;
-	int ret; 
-
-	lock_kernel();
-	D3(printk("***jffs_unlink()\n"));
-	D3(printk (KERN_NOTICE "unlink(): down biglock\n"));
-	mutex_lock(&c->fmc->biglock);
-	ret = jffs_remove(dir, dentry, 0);
-	D3(printk (KERN_NOTICE "unlink(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-	unlock_kernel();
-	return ret;
-}
-
-
-/* Remove a JFFS entry, i.e. plain files, directories, etc.  Here we
-   shouldn't test for free space on the device.  */
-static int
-jffs_remove(struct inode *dir, struct dentry *dentry, int type)
-{
-	struct jffs_raw_inode raw_inode;
-	struct jffs_control *c;
-	struct jffs_file *dir_f; /* The file-to-remove's parent.  */
-	struct jffs_file *del_f; /* The file to remove.  */
-	struct jffs_node *del_node;
-	struct inode *inode = NULL;
-	int result = 0;
-
-	D1({
-		int len = dentry->d_name.len;
-		const char *name = dentry->d_name.name;
-		char *_name = kmalloc(len + 1, GFP_KERNEL);
-		memcpy(_name, name, len);
-		_name[len] = '\0';
-		printk("***jffs_remove(): file = \"%s\", ino = %ld\n", _name, dentry->d_inode->i_ino);
-		kfree(_name);
-	});
-
-	dir_f = dir->i_private;
-	c = dir_f->c;
-
-	result = -ENOENT;
-	if (!(del_f = jffs_find_child(dir_f, dentry->d_name.name,
-				      dentry->d_name.len))) {
-		D(printk("jffs_remove(): jffs_find_child() failed.\n"));
-		goto jffs_remove_end;
-	}
-
-	if (S_ISDIR(type)) {
-		struct jffs_file *child = del_f->children;
-		while(child) {
-			if( !child->deleted ) {
-				result = -ENOTEMPTY;
-				goto jffs_remove_end;
-			}
-			child = child->sibling_next;
-		}
-	}            
-	else if (S_ISDIR(del_f->mode)) {
-		D(printk("jffs_remove(): node is a directory "
-			 "but it shouldn't be.\n"));
-		result = -EPERM;
-		goto jffs_remove_end;
-	}
-
-	inode = dentry->d_inode;
-
-	result = -EIO;
-	if (del_f->ino != inode->i_ino)
-		goto jffs_remove_end;
-
-	if (!inode->i_nlink) {
-		printk("Deleting nonexistent file inode: %lu, nlink: %d\n",
-		       inode->i_ino, inode->i_nlink);
-		inode->i_nlink=1;
-	}
-
-	/* Create a node for the deletion.  */
-	result = -ENOMEM;
-	if (!(del_node = jffs_alloc_node())) {
-		D(printk("jffs_remove(): Allocation failed!\n"));
-		goto jffs_remove_end;
-	}
-	del_node->data_offset = 0;
-	del_node->removed_size = 0;
-
-	/* Initialize the raw inode.  */
-	raw_inode.magic = JFFS_MAGIC_BITMASK;
-	raw_inode.ino = del_f->ino;
-	raw_inode.pino = del_f->pino;
-/*  	raw_inode.version = del_f->highest_version + 1; */
-	raw_inode.mode = del_f->mode;
-	raw_inode.uid = current->fsuid;
-	raw_inode.gid = current->fsgid;
-	raw_inode.atime = get_seconds();
-	raw_inode.mtime = del_f->mtime;
-	raw_inode.ctime = raw_inode.atime;
-	raw_inode.offset = 0;
-	raw_inode.dsize = 0;
-	raw_inode.rsize = 0;
-	raw_inode.nsize = 0;
-	raw_inode.nlink = del_f->nlink;
-	raw_inode.spare = 0;
-	raw_inode.rename = 0;
-	raw_inode.deleted = 1;
-
-	/* Write the new node to the flash memory.  */
-	if (jffs_write_node(c, del_node, &raw_inode, NULL, NULL, 1, del_f) < 0) {
-		jffs_free_node(del_node);
-		result = -EIO;
-		goto jffs_remove_end;
-	}
-
-	/* Update the file.  This operation will make the file disappear
-	   from the in-memory file system structures.  */
-	jffs_insert_node(c, del_f, &raw_inode, NULL, del_node);
-
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
-	mark_inode_dirty(dir);
-	inode->i_ctime = dir->i_ctime;
-	inode_dec_link_count(inode);
-
-	d_delete(dentry);	/* This also frees the inode */
-
-	result = 0;
-jffs_remove_end:
-	return result;
-} /* jffs_remove()  */
-
-
-static int
-jffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
-{
-	struct jffs_raw_inode raw_inode;
-	struct jffs_file *dir_f;
-	struct jffs_node *node = NULL;
-	struct jffs_control *c;
-	struct inode *inode;
-	int result = 0;
-	u16 data = old_encode_dev(rdev);
-	int err;
-
-	D1(printk("***jffs_mknod()\n"));
-
-	if (!old_valid_dev(rdev))
-		return -EINVAL;
-	lock_kernel();
-	dir_f = dir->i_private;
-	c = dir_f->c;
-
-	D3(printk (KERN_NOTICE "mknod(): down biglock\n"));
-	mutex_lock(&c->fmc->biglock);
-
-	/* Create and initialize a new node.  */
-	if (!(node = jffs_alloc_node())) {
-		D(printk("jffs_mknod(): Allocation failed!\n"));
-		result = -ENOMEM;
-		goto jffs_mknod_err;
-	}
-	node->data_offset = 0;
-	node->removed_size = 0;
-
-	/* Initialize the raw inode.  */
-	raw_inode.magic = JFFS_MAGIC_BITMASK;
-	raw_inode.ino = c->next_ino++;
-	raw_inode.pino = dir_f->ino;
-	raw_inode.version = 1;
-	raw_inode.mode = mode;
-	raw_inode.uid = current->fsuid;
-	raw_inode.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-	/*	raw_inode.gid = current->fsgid; */
-	raw_inode.atime = get_seconds();
-	raw_inode.mtime = raw_inode.atime;
-	raw_inode.ctime = raw_inode.atime;
-	raw_inode.offset = 0;
-	raw_inode.dsize = 2;
-	raw_inode.rsize = 0;
-	raw_inode.nsize = dentry->d_name.len;
-	raw_inode.nlink = 1;
-	raw_inode.spare = 0;
-	raw_inode.rename = 0;
-	raw_inode.deleted = 0;
-
-	/* Write the new node to the flash.  */
-	if ((err = jffs_write_node(c, node, &raw_inode, dentry->d_name.name,
-				   (unsigned char *)&data, 0, NULL)) < 0) {
-		D(printk("jffs_mknod(): jffs_write_node() failed.\n"));
-		result = err;
-		goto jffs_mknod_err;
-	}
-
-	/* Insert the new node into the file system.  */
-	if ((err = jffs_insert_node(c, NULL, &raw_inode, dentry->d_name.name,
-				    node)) < 0) {
-		result = err;
-		goto jffs_mknod_end;
-	}
-
-	inode = jffs_new_inode(dir, &raw_inode, &err);
-	if (inode == NULL) {
-		result = err;
-		goto jffs_mknod_end;
-	}
-
-	init_special_inode(inode, mode, rdev);
-
-	d_instantiate(dentry, inode);
-
-	goto jffs_mknod_end;
-
-jffs_mknod_err:
-	if (node) {
-		jffs_free_node(node);
-	}
-
-jffs_mknod_end:
-	D3(printk (KERN_NOTICE "mknod(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-	unlock_kernel();
-	return result;
-} /* jffs_mknod()  */
-
-
-static int
-jffs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
-{
-	struct jffs_raw_inode raw_inode;
-	struct jffs_control *c;
-	struct jffs_file *dir_f;
-	struct jffs_node *node;
-	struct inode *inode;
-
-	int symname_len = strlen(symname);
-	int err;
-
-	lock_kernel();
-	D1({
-		int len = dentry->d_name.len; 
-		char *_name = kmalloc(len + 1, GFP_KERNEL);
-		char *_symname = kmalloc(symname_len + 1, GFP_KERNEL);
-		memcpy(_name, dentry->d_name.name, len);
-		_name[len] = '\0';
-		memcpy(_symname, symname, symname_len);
-		_symname[symname_len] = '\0';
-		printk("***jffs_symlink(): dir = 0x%p, "
-		       "dentry->dname.name = \"%s\", "
-		       "symname = \"%s\"\n", dir, _name, _symname);
-		kfree(_name);
-		kfree(_symname);
-	});
-
-	dir_f = dir->i_private;
-	ASSERT(if (!dir_f) {
-		printk(KERN_ERR "jffs_symlink(): No reference to a "
-		       "jffs_file struct in inode.\n");
-		unlock_kernel();
-		return -EIO;
-	});
-
-	c = dir_f->c;
-
-	/* Create a node and initialize it as much as needed.  */
-	if (!(node = jffs_alloc_node())) {
-		D(printk("jffs_symlink(): Allocation failed: node = NULL\n"));
-		unlock_kernel();
-		return -ENOMEM;
-	}
-	D3(printk (KERN_NOTICE "symlink(): down biglock\n"));
-	mutex_lock(&c->fmc->biglock);
-
-	node->data_offset = 0;
-	node->removed_size = 0;
-
-	/* Initialize the raw inode.  */
-	raw_inode.magic = JFFS_MAGIC_BITMASK;
-	raw_inode.ino = c->next_ino++;
-	raw_inode.pino = dir_f->ino;
-	raw_inode.version = 1;
-	raw_inode.mode = S_IFLNK | S_IRWXUGO;
-	raw_inode.uid = current->fsuid;
-	raw_inode.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-	raw_inode.atime = get_seconds();
-	raw_inode.mtime = raw_inode.atime;
-	raw_inode.ctime = raw_inode.atime;
-	raw_inode.offset = 0;
-	raw_inode.dsize = symname_len;
-	raw_inode.rsize = 0;
-	raw_inode.nsize = dentry->d_name.len;
-	raw_inode.nlink = 1;
-	raw_inode.spare = 0;
-	raw_inode.rename = 0;
-	raw_inode.deleted = 0;
-
-	/* Write the new node to the flash.  */
-	if ((err = jffs_write_node(c, node, &raw_inode, dentry->d_name.name,
-				   (const unsigned char *)symname, 0, NULL)) < 0) {
-		D(printk("jffs_symlink(): jffs_write_node() failed.\n"));
-		jffs_free_node(node);
-		goto jffs_symlink_end;
-	}
-
-	/* Insert the new node into the file system.  */
-	if ((err = jffs_insert_node(c, NULL, &raw_inode, dentry->d_name.name,
-				    node)) < 0) {
-		goto jffs_symlink_end;
-	}
-
-	inode = jffs_new_inode(dir, &raw_inode, &err);
-	if (inode == NULL) {
-		goto jffs_symlink_end;
-	}
-	err = 0;
-	inode->i_op = &page_symlink_inode_operations;
-	inode->i_mapping->a_ops = &jffs_address_operations;
-
-	d_instantiate(dentry, inode);
- jffs_symlink_end:
-	D3(printk (KERN_NOTICE "symlink(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-	unlock_kernel();
-	return err;
-} /* jffs_symlink()  */
-
-
-/* Create an inode inside a JFFS directory (dir) and return it.
- *
- * By the time this is called, we already have created
- * the directory cache entry for the new file, but it
- * is so far negative - it has no inode.
- *
- * If the create succeeds, we fill in the inode information
- * with d_instantiate().
- */
-static int
-jffs_create(struct inode *dir, struct dentry *dentry, int mode,
-		struct nameidata *nd)
-{
-	struct jffs_raw_inode raw_inode;
-	struct jffs_control *c;
-	struct jffs_node *node;
-	struct jffs_file *dir_f; /* JFFS representation of the directory.  */
-	struct inode *inode;
-	int err;
-
-	lock_kernel();
-	D1({
-		int len = dentry->d_name.len;
-		char *s = kmalloc(len + 1, GFP_KERNEL);
-		memcpy(s, dentry->d_name.name, len);
-		s[len] = '\0';
-		printk("jffs_create(): dir: 0x%p, name: \"%s\"\n", dir, s);
-		kfree(s);
-	});
-
-	dir_f = dir->i_private;
-	ASSERT(if (!dir_f) {
-		printk(KERN_ERR "jffs_create(): No reference to a "
-		       "jffs_file struct in inode.\n");
-		unlock_kernel();
-		return -EIO;
-	});
-
-	c = dir_f->c;
-
-	/* Create a node and initialize as much as needed.  */
-	if (!(node = jffs_alloc_node())) {
-		D(printk("jffs_create(): Allocation failed: node == 0\n"));
-		unlock_kernel();
-		return -ENOMEM;
-	}
-	D3(printk (KERN_NOTICE "create(): down biglock\n"));
-	mutex_lock(&c->fmc->biglock);
-
-	node->data_offset = 0;
-	node->removed_size = 0;
-
-	/* Initialize the raw inode.  */
-	raw_inode.magic = JFFS_MAGIC_BITMASK;
-	raw_inode.ino = c->next_ino++;
-	raw_inode.pino = dir_f->ino;
-	raw_inode.version = 1;
-	raw_inode.mode = mode;
-	raw_inode.uid = current->fsuid;
-	raw_inode.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-	raw_inode.atime = get_seconds();
-	raw_inode.mtime = raw_inode.atime;
-	raw_inode.ctime = raw_inode.atime;
-	raw_inode.offset = 0;
-	raw_inode.dsize = 0;
-	raw_inode.rsize = 0;
-	raw_inode.nsize = dentry->d_name.len;
-	raw_inode.nlink = 1;
-	raw_inode.spare = 0;
-	raw_inode.rename = 0;
-	raw_inode.deleted = 0;
-
-	/* Write the new node to the flash.  */
-	if ((err = jffs_write_node(c, node, &raw_inode,
-				   dentry->d_name.name, NULL, 0, NULL)) < 0) {
-		D(printk("jffs_create(): jffs_write_node() failed.\n"));
-		jffs_free_node(node);
-		goto jffs_create_end;
-	}
-
-	/* Insert the new node into the file system.  */
-	if ((err = jffs_insert_node(c, NULL, &raw_inode, dentry->d_name.name,
-				    node)) < 0) {
-		goto jffs_create_end;
-	}
-
-	/* Initialize an inode.  */
-	inode = jffs_new_inode(dir, &raw_inode, &err);
-	if (inode == NULL) {
-		goto jffs_create_end;
-	}
-	err = 0;
-	inode->i_op = &jffs_file_inode_operations;
-	inode->i_fop = &jffs_file_operations;
-	inode->i_mapping->a_ops = &jffs_address_operations;
-	inode->i_mapping->nrpages = 0;
-
-	d_instantiate(dentry, inode);
- jffs_create_end:
-	D3(printk (KERN_NOTICE "create(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-	unlock_kernel();
-	return err;
-} /* jffs_create()  */
-
-
-/* Write, append or rewrite data to an existing file.  */
-static ssize_t
-jffs_file_write(struct file *filp, const char *buf, size_t count,
-		loff_t *ppos)
-{
-	struct jffs_raw_inode raw_inode;
-	struct jffs_control *c;
-	struct jffs_file *f;
-	struct jffs_node *node;
-	struct dentry *dentry = filp->f_path.dentry;
-	struct inode *inode = dentry->d_inode;
-	int recoverable = 0;
-	size_t written = 0;
-	__u32 thiscount = count;
-	loff_t pos = *ppos;
-	int err;
-
-	inode = filp->f_path.dentry->d_inode;
-
-	D2(printk("***jffs_file_write(): inode: 0x%p (ino: %lu), "
-		  "filp: 0x%p, buf: 0x%p, count: %d\n",
-		  inode, inode->i_ino, filp, buf, count));
-
-#if 0
-	if (inode->i_sb->s_flags & MS_RDONLY) {
-		D(printk("jffs_file_write(): MS_RDONLY\n"));
-		err = -EROFS;
-		goto out_isem;
-	}
-#endif	
-	err = -EINVAL;
-
-	if (!S_ISREG(inode->i_mode)) {
-		D(printk("jffs_file_write(): inode->i_mode == 0x%08x\n",
-				inode->i_mode));
-		goto out_isem;
-	}
-
-	if (!(f = inode->i_private)) {
-		D(printk("jffs_file_write(): inode->i_private = 0x%p\n",
-				inode->i_private));
-		goto out_isem;
-	}
-
-	c = f->c;
-
-	/*
-	 * This will never trigger with sane page sizes.  leave it in
-	 * anyway, since I'm thinking about how to merge larger writes
-	 * (the current idea is to poke a thread that does the actual
-	 * I/O and starts by doing a mutex_lock(&inode->i_mutex).  then we
-	 * would need to get the page cache pages and have a list of
-	 * I/O requests and do write-merging here.
-	 * -- prumpf
-	 */
-	thiscount = min(c->fmc->max_chunk_size - sizeof(struct jffs_raw_inode), count);
-
-	D3(printk (KERN_NOTICE "file_write(): down biglock\n"));
-	mutex_lock(&c->fmc->biglock);
-
-	/* Urgh. POSIX says we can do short writes if we feel like it. 
-	 * In practice, we can't. Nothing will cope. So we loop until
-	 * we're done.
-	 *
-	 * <_Anarchy_> posix and reality are not interconnected on this issue
-	 */
-	while (count) {
-		/* Things are going to be written so we could allocate and
-		   initialize the necessary data structures now.  */
-		if (!(node = jffs_alloc_node())) {
-			D(printk("jffs_file_write(): node == 0\n"));
-			err = -ENOMEM;
-			goto out;
-		}
-
-		node->data_offset = pos;
-		node->removed_size = 0;
-
-		/* Initialize the raw inode.  */
-		raw_inode.magic = JFFS_MAGIC_BITMASK;
-		raw_inode.ino = f->ino;
-		raw_inode.pino = f->pino;
-
-		raw_inode.mode = f->mode;
-
-		raw_inode.uid = f->uid;
-		raw_inode.gid = f->gid;
-		raw_inode.atime = get_seconds();
-		raw_inode.mtime = raw_inode.atime;
-		raw_inode.ctime = f->ctime;
-		raw_inode.offset = pos;
-		raw_inode.dsize = thiscount;
-		raw_inode.rsize = 0;
-		raw_inode.nsize = f->nsize;
-		raw_inode.nlink = f->nlink;
-		raw_inode.spare = 0;
-		raw_inode.rename = 0;
-		raw_inode.deleted = 0;
-
-		if (pos < f->size) {
-			node->removed_size = raw_inode.rsize = min(thiscount, (__u32)(f->size - pos));
-
-			/* If this node is going entirely over the top of old data,
-			   we can allow it to go into the reserved space, because
-			   we know that GC can reclaim the space later.
-			*/
-			if (pos + thiscount < f->size) {
-				/* If all the data we're overwriting are _real_,
-				   not just holes, then:
-				   recoverable = 1;
-				*/
-			}
-		}
-
-		/* Write the new node to the flash.  */
-		/* NOTE: We would be quite happy if jffs_write_node() wrote a
-		   smaller node than we were expecting. There's no need for it
-		   to waste the space at the end of the flash just because it's
-		   a little smaller than what we asked for. But that's a whole
-		   new can of worms which I'm not going to open this week. 
-		   -- dwmw2.
-		*/
-		if ((err = jffs_write_node(c, node, &raw_inode, f->name,
-					   (const unsigned char *)buf,
-					   recoverable, f)) < 0) {
-			D(printk("jffs_file_write(): jffs_write_node() failed.\n"));
-			jffs_free_node(node);
-			goto out;
-		}
-
-		written += err;
-		buf += err;
-		count -= err;
-		pos += err;
-
-		/* Insert the new node into the file system.  */
-		if ((err = jffs_insert_node(c, f, &raw_inode, NULL, node)) < 0) {
-			goto out;
-		}
-
-		D3(printk("jffs_file_write(): new f_pos %ld.\n", (long)pos));
-
-		thiscount = min(c->fmc->max_chunk_size - sizeof(struct jffs_raw_inode), count);
-	}
- out:
-	D3(printk (KERN_NOTICE "file_write(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-
-	/* Fix things in the real inode.  */
-	if (pos > inode->i_size) {
-		inode->i_size = pos;
-		inode->i_blocks = (inode->i_size + 511) >> 9;
-	}
-	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
-	mark_inode_dirty(inode);
-	invalidate_mapping_pages(inode->i_mapping, 0, -1);
-
- out_isem:
-	return err;
-} /* jffs_file_write()  */
-
-static int
-jffs_prepare_write(struct file *filp, struct page *page,
-                  unsigned from, unsigned to)
-{
-	/* FIXME: we should detect some error conditions here */
-
-	/* Bugger that. We should make sure the page is uptodate */
-	if (!PageUptodate(page) && (from || to < PAGE_CACHE_SIZE))
-		return jffs_do_readpage_nolock(filp, page);
-
-	return 0;
-} /* jffs_prepare_write() */
-
-static int
-jffs_commit_write(struct file *filp, struct page *page,
-                 unsigned from, unsigned to)
-{
-       void *addr = page_address(page) + from;
-       /* XXX: PAGE_CACHE_SHIFT or PAGE_SHIFT */
-       loff_t pos = page_offset(page) + from;
-
-       return jffs_file_write(filp, addr, to-from, &pos);
-} /* jffs_commit_write() */
-
-/* This is our ioctl() routine.  */
-static int
-jffs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-	   unsigned long arg)
-{
-	struct jffs_control *c;
-	int ret = 0;
-
-	D2(printk("***jffs_ioctl(): cmd = 0x%08x, arg = 0x%08lx\n",
-		  cmd, arg));
-
-	if (!(c = (struct jffs_control *)inode->i_sb->s_fs_info)) {
-		printk(KERN_ERR "JFFS: Bad inode in ioctl() call. "
-		       "(cmd = 0x%08x)\n", cmd);
-		return -EIO;
-	}
-	D3(printk (KERN_NOTICE "ioctl(): down biglock\n"));
-	mutex_lock(&c->fmc->biglock);
-
-	switch (cmd) {
-	case JFFS_PRINT_HASH:
-		jffs_print_hash_table(c);
-		break;
-	case JFFS_PRINT_TREE:
-		jffs_print_tree(c->root, 0);
-		break;
-	case JFFS_GET_STATUS:
-		{
-			struct jffs_flash_status fst;
-			struct jffs_fmcontrol *fmc = c->fmc;
-			printk("Flash status -- ");
-			if (!access_ok(VERIFY_WRITE,
-				       (struct jffs_flash_status __user *)arg,
-				       sizeof(struct jffs_flash_status))) {
-				D(printk("jffs_ioctl(): Bad arg in "
-					 "JFFS_GET_STATUS ioctl!\n"));
-				ret = -EFAULT;
-				break;
-			}
-			fst.size = fmc->flash_size;
-			fst.used = fmc->used_size;
-			fst.dirty = fmc->dirty_size;
-			fst.begin = fmc->head->offset;
-			fst.end = fmc->tail->offset + fmc->tail->size;
-			printk("size: %d, used: %d, dirty: %d, "
-			       "begin: %d, end: %d\n",
-			       fst.size, fst.used, fst.dirty,
-			       fst.begin, fst.end);
-			if (copy_to_user((struct jffs_flash_status __user *)arg,
-					 &fst,
-					 sizeof(struct jffs_flash_status))) {
-				ret = -EFAULT;
-			}
-		}
-		break;
-	default:
-		ret = -ENOTTY;
-	}
-	D3(printk (KERN_NOTICE "ioctl(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-	return ret;
-} /* jffs_ioctl()  */
-
-
-static const struct address_space_operations jffs_address_operations = {
-	.readpage	= jffs_readpage,
-	.prepare_write	= jffs_prepare_write,
-	.commit_write	= jffs_commit_write,
-};
-
-static int jffs_fsync(struct file *f, struct dentry *d, int datasync)
-{
-	/* We currently have O_SYNC operations at all times.
-	   Do nothing.
-	*/
-	return 0;
-}
-
-
-static const struct file_operations jffs_file_operations =
-{
-	.open		= generic_file_open,
-	.llseek		= generic_file_llseek,
-	.read		= do_sync_read,
-	.aio_read	= generic_file_aio_read,
-	.write		= do_sync_write,
-	.aio_write	= generic_file_aio_write,
-	.ioctl		= jffs_ioctl,
-	.mmap		= generic_file_readonly_mmap,
-	.fsync		= jffs_fsync,
-	.sendfile	= generic_file_sendfile,
-};
-
-
-static const struct inode_operations jffs_file_inode_operations =
-{
-	.lookup		= jffs_lookup,          /* lookup */
-	.setattr	= jffs_setattr,
-};
-
-
-static const struct file_operations jffs_dir_operations =
-{
-	.readdir	= jffs_readdir,
-};
-
-
-static const struct inode_operations jffs_dir_inode_operations =
-{
-	.create		= jffs_create,
-	.lookup		= jffs_lookup,
-	.unlink		= jffs_unlink,
-	.symlink	= jffs_symlink,
-	.mkdir		= jffs_mkdir,
-	.rmdir		= jffs_rmdir,
-	.mknod		= jffs_mknod,
-	.rename		= jffs_rename,
-	.setattr	= jffs_setattr,
-};
-
-
-/* Initialize an inode for the VFS.  */
-static void
-jffs_read_inode(struct inode *inode)
-{
-	struct jffs_file *f;
-	struct jffs_control *c;
-
-	D3(printk("jffs_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
-
-	if (!inode->i_sb) {
-		D(printk("jffs_read_inode(): !inode->i_sb ==> "
-			 "No super block!\n"));
-		return;
-	}
-	c = (struct jffs_control *)inode->i_sb->s_fs_info;
-	D3(printk (KERN_NOTICE "read_inode(): down biglock\n"));
-	mutex_lock(&c->fmc->biglock);
-	if (!(f = jffs_find_file(c, inode->i_ino))) {
-		D(printk("jffs_read_inode(): No such inode (%lu).\n",
-			 inode->i_ino));
-		D3(printk (KERN_NOTICE "read_inode(): up biglock\n"));
-		mutex_unlock(&c->fmc->biglock);
-		return;
-	}
-	inode->i_private = f;
-	inode->i_mode = f->mode;
-	inode->i_nlink = f->nlink;
-	inode->i_uid = f->uid;
-	inode->i_gid = f->gid;
-	inode->i_size = f->size;
-	inode->i_atime.tv_sec = f->atime;
-	inode->i_mtime.tv_sec = f->mtime;
-	inode->i_ctime.tv_sec = f->ctime;
-	inode->i_atime.tv_nsec = 
-	inode->i_mtime.tv_nsec = 
-	inode->i_ctime.tv_nsec = 0;
-
-	inode->i_blocks = (inode->i_size + 511) >> 9;
-	if (S_ISREG(inode->i_mode)) {
-		inode->i_op = &jffs_file_inode_operations;
-		inode->i_fop = &jffs_file_operations;
-		inode->i_mapping->a_ops = &jffs_address_operations;
-	}
-	else if (S_ISDIR(inode->i_mode)) {
-		inode->i_op = &jffs_dir_inode_operations;
-		inode->i_fop = &jffs_dir_operations;
-	}
-	else if (S_ISLNK(inode->i_mode)) {
-		inode->i_op = &page_symlink_inode_operations;
-		inode->i_mapping->a_ops = &jffs_address_operations;
-	}
-	else {
-		/* If the node is a device of some sort, then the number of
-		   the device should be read from the flash memory and then
-		   added to the inode's i_rdev member.  */
-		u16 val;
-		jffs_read_data(f, (char *)&val, 0, 2);
-		init_special_inode(inode, inode->i_mode,
-			old_decode_dev(val));
-	}
-
-	D3(printk (KERN_NOTICE "read_inode(): up biglock\n"));
-	mutex_unlock(&c->fmc->biglock);
-}
-
-
-static void
-jffs_delete_inode(struct inode *inode)
-{
-	struct jffs_file *f;
-	struct jffs_control *c;
-	D3(printk("jffs_delete_inode(): inode->i_ino == %lu\n",
-		  inode->i_ino));
-
-	truncate_inode_pages(&inode->i_data, 0);
-	lock_kernel();
-	inode->i_size = 0;
-	inode->i_blocks = 0;
-	inode->i_private = NULL;
-	clear_inode(inode);
-	if (inode->i_nlink == 0) {
-		c = (struct jffs_control *) inode->i_sb->s_fs_info;
-		f = (struct jffs_file *) jffs_find_file (c, inode->i_ino);
-		jffs_possibly_delete_file(f);
-	}
-
-	unlock_kernel();
-}
-
-
-static void
-jffs_write_super(struct super_block *sb)
-{
-	struct jffs_control *c = (struct jffs_control *)sb->s_fs_info;
-	lock_kernel();
-	jffs_garbage_collect_trigger(c);
-	unlock_kernel();
-}
-
-static int jffs_remount(struct super_block *sb, int *flags, char *data)
-{
-	*flags |= MS_NODIRATIME;
-	return 0;
-}
-
-static const struct super_operations jffs_ops =
-{
-	.read_inode	= jffs_read_inode,
-	.delete_inode 	= jffs_delete_inode,
-	.put_super	= jffs_put_super,
-	.write_super	= jffs_write_super,
-	.statfs		= jffs_statfs,
-	.remount_fs	= jffs_remount,
-};
-
-static int jffs_get_sb(struct file_system_type *fs_type,
-	int flags, const char *dev_name, void *data, struct vfsmount *mnt)
-{
-	return get_sb_bdev(fs_type, flags, dev_name, data, jffs_fill_super,
-			   mnt);
-}
-
-static struct file_system_type jffs_fs_type = {
-	.owner		= THIS_MODULE,
-	.name		= "jffs",
-	.get_sb		= jffs_get_sb,
-	.kill_sb	= kill_block_super,
-	.fs_flags	= FS_REQUIRES_DEV,
-};
-
-static int __init
-init_jffs_fs(void)
-{
-	printk(KERN_INFO "JFFS version " JFFS_VERSION_STRING
-		", (C) 1999, 2000  Axis Communications AB\n");
-	
-#ifdef CONFIG_JFFS_PROC_FS
-	jffs_proc_root = proc_mkdir("jffs", proc_root_fs);
-	if (!jffs_proc_root) {
-		printk(KERN_WARNING "cannot create /proc/jffs entry\n");
-	}
-#endif
-	fm_cache = kmem_cache_create("jffs_fm", sizeof(struct jffs_fm),
-		       0,
-		       SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD,
-		       NULL, NULL);
-	if (!fm_cache) {
-		return -ENOMEM;
-	}
-
-	node_cache = kmem_cache_create("jffs_node",sizeof(struct jffs_node),
-		       0,
-		       SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD,
-		       NULL, NULL);
-	if (!node_cache) {
-		kmem_cache_destroy(fm_cache);
-		return -ENOMEM;
-	}
-
-	return register_filesystem(&jffs_fs_type);
-}
-
-static void __exit
-exit_jffs_fs(void)
-{
-	unregister_filesystem(&jffs_fs_type);
-	kmem_cache_destroy(fm_cache);
-	kmem_cache_destroy(node_cache);
-}
-
-module_init(init_jffs_fs)
-module_exit(exit_jffs_fs)
-
-MODULE_DESCRIPTION("The Journalling Flash File System");
-MODULE_AUTHOR("Axis Communications AB.");
-MODULE_LICENSE("GPL");
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c
deleted file mode 100644
index 6dd1891..0000000
--- a/fs/jffs/intrep.c
+++ /dev/null
@@ -1,3449 +0,0 @@
-/*
- * JFFS -- Journaling Flash File System, Linux implementation.
- *
- * Copyright (C) 1999, 2000  Axis Communications, Inc.
- *
- * Created by Finn Hakansson <finn@axis.com>.
- *
- * This 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.
- *
- * $Id: intrep.c,v 1.102 2001/09/23 23:28:36 dwmw2 Exp $
- *
- * Ported to Linux 2.3.x and MTD:
- * Copyright (C) 2000  Alexander Larsson (alex@cendio.se), Cendio Systems AB
- *
- */
-
-/* This file contains the code for the internal structure of the
-   Journaling Flash File System, JFFS.  */
-
-/*
- * Todo list:
- *
- * memcpy_to_flash() and memcpy_from_flash() functions.
- *
- * Implementation of hard links.
- *
- * Organize the source code in a better way. Against the VFS we could
- * have jffs_ext.c, and against the block device jffs_int.c.
- * A better file-internal organization too.
- *
- * A better checksum algorithm.
- *
- * Consider endianness stuff. ntohl() etc.
- *
- * Are we handling the atime, mtime, ctime members of the inode right?
- *
- * Remove some duplicated code. Take a look at jffs_write_node() and
- * jffs_rewrite_data() for instance.
- *
- * Implement more meaning of the nlink member in various data structures.
- * nlink could be used in conjunction with hard links for instance.
- *
- * Better memory management. Allocate data structures in larger chunks
- * if possible.
- *
- * If too much meta data is stored, a garbage collect should be issued.
- * We have experienced problems with too much meta data with for instance
- * log files.
- *
- * Improve the calls to jffs_ioctl(). We would like to retrieve more
- * information to be able to debug (or to supervise) JFFS during run-time.
- *
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/jffs.h>
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <linux/pagemap.h>
-#include <linux/mutex.h>
-#include <asm/byteorder.h>
-#include <linux/smp_lock.h>
-#include <linux/time.h>
-#include <linux/ctype.h>
-#include <linux/freezer.h>
-
-#include "intrep.h"
-#include "jffs_fm.h"
-
-long no_jffs_node = 0;
-static long no_jffs_file = 0;
-#if defined(JFFS_MEMORY_DEBUG) && JFFS_MEMORY_DEBUG
-long no_jffs_control = 0;
-long no_jffs_raw_inode = 0;
-long no_jffs_node_ref = 0;
-long no_jffs_fm = 0;
-long no_jffs_fmcontrol = 0;
-long no_hash = 0;
-long no_name = 0;
-#endif
-
-static int jffs_scan_flash(struct jffs_control *c);
-static int jffs_update_file(struct jffs_file *f, struct jffs_node *node);
-static int jffs_build_file(struct jffs_file *f);
-static int jffs_free_file(struct jffs_file *f);
-static int jffs_free_node_list(struct jffs_file *f);
-static int jffs_garbage_collect_now(struct jffs_control *c);
-static int jffs_insert_file_into_hash(struct jffs_file *f);
-static int jffs_remove_redundant_nodes(struct jffs_file *f);
-
-/* Is there enough space on the flash?  */
-static inline int JFFS_ENOUGH_SPACE(struct jffs_control *c, __u32 space)
-{
-	struct jffs_fmcontrol *fmc = c->fmc;
-
-	while (1) {
-		if ((fmc->flash_size - (fmc->used_size + fmc->dirty_size))
-			>= fmc->min_free_size + space) {
-			return 1;
-		}
-		if (fmc->dirty_size < fmc->sector_size)
-			return 0;
-
-		if (jffs_garbage_collect_now(c)) {
-		  D1(printk("JFFS_ENOUGH_SPACE: jffs_garbage_collect_now() failed.\n"));
-		  return 0;
-		}
-	}
-}
-
-#if CONFIG_JFFS_FS_VERBOSE > 0
-static __u8
-flash_read_u8(struct mtd_info *mtd, loff_t from)
-{
-	size_t retlen;
-	__u8 ret;
-	int res;
-
-	res = MTD_READ(mtd, from, 1, &retlen, &ret);
-	if (retlen != 1) {
-		printk("Didn't read a byte in flash_read_u8(). Returned %d\n", res);
-		return 0;
-	}
-
-	return ret;
-}
-
-static void
-jffs_hexdump(struct mtd_info *mtd, loff_t pos, int size)
-{
-	char line[16];
-	int j = 0;
-
-	while (size > 0) {
-		int i;
-
-		printk("%ld:", (long) pos);
-		for (j = 0; j < 16; j++) {
-			line[j] = flash_read_u8(mtd, pos++);
-		}
-		for (i = 0; i < j; i++) {
-			if (!(i & 1)) {
-				printk(" %.2x", line[i] & 0xff);
-			}
-			else {
-				printk("%.2x", line[i] & 0xff);
-			}
-		}
-
-		/* Print empty space */
-		for (; i < 16; i++) {
-			if (!(i & 1)) {
-				printk("   ");
-			}
-			else {
-				printk("  ");
-			}
-		}
-		printk("  ");
-
-		for (i = 0; i < j; i++) {
-			if (isgraph(line[i])) {
-				printk("%c", line[i]);
-			}
-			else {
-				printk(".");
-			}
-		}
-		printk("\n");
-		size -= 16;
-	}
-}
-
-/* Print the contents of a node.  */
-static void
-jffs_print_node(struct jffs_node *n)
-{
-	D(printk("jffs_node: 0x%p\n", n));
-	D(printk("{\n"));
-	D(printk("        0x%08x, /* version  */\n", n->version));
-	D(printk("        0x%08x, /* data_offset  */\n", n->data_offset));
-	D(printk("        0x%08x, /* data_size  */\n", n->data_size));
-	D(printk("        0x%08x, /* removed_size  */\n", n->removed_size));
-	D(printk("        0x%08x, /* fm_offset  */\n", n->fm_offset));
-	D(printk("        0x%02x,       /* name_size  */\n", n->name_size));
-	D(printk("        0x%p, /* fm,  fm->offset: %u  */\n",
-		 n->fm, (n->fm ? n->fm->offset : 0)));
-	D(printk("        0x%p, /* version_prev  */\n", n->version_prev));
-	D(printk("        0x%p, /* version_next  */\n", n->version_next));
-	D(printk("        0x%p, /* range_prev  */\n", n->range_prev));
-	D(printk("        0x%p, /* range_next  */\n", n->range_next));
-	D(printk("}\n"));
-}
-
-#endif
-
-/* Print the contents of a raw inode.  */
-static void
-jffs_print_raw_inode(struct jffs_raw_inode *raw_inode)
-{
-	D(printk("jffs_raw_inode: inode number: %u\n", raw_inode->ino));
-	D(printk("{\n"));
-	D(printk("        0x%08x, /* magic  */\n", raw_inode->magic));
-	D(printk("        0x%08x, /* ino  */\n", raw_inode->ino));
-	D(printk("        0x%08x, /* pino  */\n", raw_inode->pino));
-	D(printk("        0x%08x, /* version  */\n", raw_inode->version));
-	D(printk("        0x%08x, /* mode  */\n", raw_inode->mode));
-	D(printk("        0x%04x,     /* uid  */\n", raw_inode->uid));
-	D(printk("        0x%04x,     /* gid  */\n", raw_inode->gid));
-	D(printk("        0x%08x, /* atime  */\n", raw_inode->atime));
-	D(printk("        0x%08x, /* mtime  */\n", raw_inode->mtime));
-	D(printk("        0x%08x, /* ctime  */\n", raw_inode->ctime));
-	D(printk("        0x%08x, /* offset  */\n", raw_inode->offset));
-	D(printk("        0x%08x, /* dsize  */\n", raw_inode->dsize));
-	D(printk("        0x%08x, /* rsize  */\n", raw_inode->rsize));
-	D(printk("        0x%02x,       /* nsize  */\n", raw_inode->nsize));
-	D(printk("        0x%02x,       /* nlink  */\n", raw_inode->nlink));
-	D(printk("        0x%02x,       /* spare  */\n",
-		 raw_inode->spare));
-	D(printk("        %u,          /* rename  */\n",
-		 raw_inode->rename));
-	D(printk("        %u,          /* deleted  */\n",
-		 raw_inode->deleted));
-	D(printk("        0x%02x,       /* accurate  */\n",
-		 raw_inode->accurate));
-	D(printk("        0x%08x, /* dchksum  */\n", raw_inode->dchksum));
-	D(printk("        0x%04x,     /* nchksum  */\n", raw_inode->nchksum));
-	D(printk("        0x%04x,     /* chksum  */\n", raw_inode->chksum));
-	D(printk("}\n"));
-}
-
-#define flash_safe_acquire(arg)
-#define flash_safe_release(arg)
-
-
-static int
-flash_safe_read(struct mtd_info *mtd, loff_t from,
-		u_char *buf, size_t count)
-{
-	size_t retlen;
-	int res;
-
-	D3(printk(KERN_NOTICE "flash_safe_read(%p, %08x, %p, %08x)\n",
-		  mtd, (unsigned int) from, buf, count));
-
-	res = mtd->read(mtd, from, count, &retlen, buf);
-	if (retlen != count) {
-		panic("Didn't read all bytes in flash_safe_read(). Returned %d\n", res);
-	}
-	return res?res:retlen;
-}
-
-
-static __u32
-flash_read_u32(struct mtd_info *mtd, loff_t from)
-{
-	size_t retlen;
-	__u32 ret;
-	int res;
-
-	res = mtd->read(mtd, from, 4, &retlen, (unsigned char *)&ret);
-	if (retlen != 4) {
-		printk("Didn't read all bytes in flash_read_u32(). Returned %d\n", res);
-		return 0;
-	}
-
-	return ret;
-}
-
-
-static int
-flash_safe_write(struct mtd_info *mtd, loff_t to,
-		 const u_char *buf, size_t count)
-{
-	size_t retlen;
-	int res;
-
-	D3(printk(KERN_NOTICE "flash_safe_write(%p, %08x, %p, %08x)\n",
-		  mtd, (unsigned int) to, buf, count));
-
-	res = mtd->write(mtd, to, count, &retlen, buf);
-	if (retlen != count) {
-		printk("Didn't write all bytes in flash_safe_write(). Returned %d\n", res);
-	}
-	return res?res:retlen;
-}
-
-
-static int
-flash_safe_writev(struct mtd_info *mtd, const struct kvec *vecs,
-			unsigned long iovec_cnt, loff_t to)
-{
-	size_t retlen, retlen_a;
-	int i;
-	int res;
-
-	D3(printk(KERN_NOTICE "flash_safe_writev(%p, %08x, %p)\n",
-		  mtd, (unsigned int) to, vecs));
-
-	if (mtd->writev) {
-		res = mtd->writev(mtd, vecs, iovec_cnt, to, &retlen);
-		return res ? res : retlen;
-	}
-	/* Not implemented writev. Repeatedly use write - on the not so
-	   unreasonable assumption that the mtd driver doesn't care how
-	   many write cycles we use. */
-	res=0;
-	retlen=0;
-
-	for (i=0; !res && i<iovec_cnt; i++) {
-		res = mtd->write(mtd, to, vecs[i].iov_len, &retlen_a,
-				 vecs[i].iov_base);
-		if (retlen_a != vecs[i].iov_len) {
-			printk("Didn't write all bytes in flash_safe_writev(). Returned %d\n", res);
-			if (i != iovec_cnt-1)
-				return -EIO;
-		}
-		/* If res is non-zero, retlen_a is undefined, but we don't
-		   care because in that case it's not going to be 
-		   returned anyway.
-		*/
-		to += retlen_a;
-		retlen += retlen_a;
-	}
-	return res?res:retlen;
-}
-
-
-static int
-flash_memset(struct mtd_info *mtd, loff_t to,
-	     const u_char c, size_t size)
-{
-	static unsigned char pattern[64];
-	int i;
-
-	/* fill up pattern */
-
-	for(i = 0; i < 64; i++)
-		pattern[i] = c;
-
-	/* write as many 64-byte chunks as we can */
-
-	while (size >= 64) {
-		flash_safe_write(mtd, to, pattern, 64);
-		size -= 64;
-		to += 64;
-	}
-
-	/* and the rest */
-
-	if(size)
-		flash_safe_write(mtd, to, pattern, size);
-
-	return size;
-}
-
-
-static void
-intrep_erase_callback(struct erase_info *done)
-{
-	wait_queue_head_t *wait_q;
-
-	wait_q = (wait_queue_head_t *)done->priv;
-
-	wake_up(wait_q);
-}
-
-
-static int
-flash_erase_region(struct mtd_info *mtd, loff_t start,
-		   size_t size)
-{
-	struct erase_info *erase;
-	DECLARE_WAITQUEUE(wait, current);
-	wait_queue_head_t wait_q;
-
-	erase = kmalloc(sizeof(struct erase_info), GFP_KERNEL);
-	if (!erase)
-		return -ENOMEM;
-
-	init_waitqueue_head(&wait_q);
-
-	erase->mtd = mtd;
-	erase->callback = intrep_erase_callback;
-	erase->addr = start;
-	erase->len = size;
-	erase->priv = (u_long)&wait_q;
-
-	/* FIXME: Use TASK_INTERRUPTIBLE and deal with being interrupted */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	add_wait_queue(&wait_q, &wait);
-
-	if (mtd->erase(mtd, erase) < 0) {
-		set_current_state(TASK_RUNNING);
-		remove_wait_queue(&wait_q, &wait);
-		kfree(erase);
-
-		printk(KERN_WARNING "flash: erase of region [0x%lx, 0x%lx] "
-		       "totally failed\n", (long)start, (long)start + size);
-
-		return -1;
-	}
-
-	schedule(); /* Wait for flash to finish. */
-	remove_wait_queue(&wait_q, &wait);
-
-	kfree(erase);
-
-	return 0;
-}
-
-/* This routine calculates checksums in JFFS.  */
-static __u32
-jffs_checksum(const void *data, int size)
-{
-	__u32 sum = 0;
-	__u8 *ptr = (__u8 *)data;
-	while (size-- > 0) {
-		sum += *ptr++;
-	}
-	D3(printk(", result: 0x%08x\n", sum));
-	return sum;
-}
-
-
-static int
-jffs_checksum_flash(struct mtd_info *mtd, loff_t start, int size, __u32 *result)
-{
-	__u32 sum = 0;
-	loff_t ptr = start;
-	__u8 *read_buf;
-	int i, length;
-
-	/* Allocate read buffer */
-	read_buf = kmalloc(sizeof(__u8) * 4096, GFP_KERNEL);
-	if (!read_buf) {
-		printk(KERN_NOTICE "kmalloc failed in jffs_checksum_flash()\n");
-		return -ENOMEM;
-	}
-	/* Loop until checksum done */
-	while (size) {
-		/* Get amount of data to read */
-		if (size < 4096)
-			length = size;
-		else
-			length = 4096;
-
-		/* Perform flash read */
-		D3(printk(KERN_NOTICE "jffs_checksum_flash\n"));
-		flash_safe_read(mtd, ptr, &read_buf[0], length);
-
-		/* Compute checksum */
-		for (i=0; i < length ; i++)
-			sum += read_buf[i];
-
-		/* Update pointer and size */
-		size -= length;
-		ptr += length;
-	}
-
-	/* Free read buffer */
-	kfree(read_buf);
-
-	/* Return result */
-	D3(printk("checksum result: 0x%08x\n", sum));
-	*result = sum;
-	return 0;
-}
-
-static __inline__ void jffs_fm_write_lock(struct jffs_fmcontrol *fmc)
-{
-  //	down(&fmc->wlock);
-}
-
-static __inline__ void jffs_fm_write_unlock(struct jffs_fmcontrol *fmc)
-{
-  //	up(&fmc->wlock);
-}
-
-
-/* Create and initialize a new struct jffs_file.  */
-static struct jffs_file *
-jffs_create_file(struct jffs_control *c,
-		 const struct jffs_raw_inode *raw_inode)
-{
-	struct jffs_file *f;
-
-	if (!(f = kzalloc(sizeof(*f), GFP_KERNEL))) {
-		D(printk("jffs_create_file(): Failed!\n"));
-		return NULL;
-	}
-	no_jffs_file++;
-	f->ino = raw_inode->ino;
-	f->pino = raw_inode->pino;
-	f->nlink = raw_inode->nlink;
-	f->deleted = raw_inode->deleted;
-	f->c = c;
-
-	return f;
-}
-
-
-/* Build a control block for the file system.  */
-static struct jffs_control *
-jffs_create_control(struct super_block *sb)
-{
-	struct jffs_control *c;
-	register int s = sizeof(struct jffs_control);
-	int i;
-	D(char *t = 0);
-
-	D2(printk("jffs_create_control()\n"));
-
-	if (!(c = kmalloc(s, GFP_KERNEL))) {
-		goto fail_control;
-	}
-	DJM(no_jffs_control++);
-	c->root = NULL;
-	c->gc_task = NULL;
-	c->hash_len = JFFS_HASH_SIZE;
-	s = sizeof(struct list_head) * c->hash_len;
-	if (!(c->hash = kmalloc(s, GFP_KERNEL))) {
-		goto fail_hash;
-	}
-	DJM(no_hash++);
-	for (i = 0; i < c->hash_len; i++)
-		INIT_LIST_HEAD(&c->hash[i]);
-	if (!(c->fmc = jffs_build_begin(c, MINOR(sb->s_dev)))) {
-		goto fail_fminit;
-	}
-	c->next_ino = JFFS_MIN_INO + 1;
-	c->delete_list = (struct jffs_delete_list *) 0;
-	return c;
-
-fail_fminit:
-	D(t = "c->fmc");
-fail_hash:
-	kfree(c);
-	DJM(no_jffs_control--);
-	D(t = t ? t : "c->hash");
-fail_control:
-	D(t = t ? t : "control");
-	D(printk("jffs_create_control(): Allocation failed: (%s)\n", t));
-	return (struct jffs_control *)0;
-}
-
-
-/* Clean up all data structures associated with the file system.  */
-void
-jffs_cleanup_control(struct jffs_control *c)
-{
-	D2(printk("jffs_cleanup_control()\n"));
-
-	if (!c) {
-		D(printk("jffs_cleanup_control(): c == NULL !!!\n"));
-		return;
-	}
-
-	while (c->delete_list) {
-		struct jffs_delete_list *delete_list_element;
-		delete_list_element = c->delete_list;
-		c->delete_list = c->delete_list->next;
-		kfree(delete_list_element);
-	}
-
-	/* Free all files and nodes.  */
-	if (c->hash) {
-		jffs_foreach_file(c, jffs_free_node_list);
-		jffs_foreach_file(c, jffs_free_file);
-		kfree(c->hash);
-		DJM(no_hash--);
-	}
-	jffs_cleanup_fmcontrol(c->fmc);
-	kfree(c);
-	DJM(no_jffs_control--);
-	D3(printk("jffs_cleanup_control(): Leaving...\n"));
-}
-
-
-/* This function adds a virtual root node to the in-RAM representation.
-   Called by jffs_build_fs().  */
-static int
-jffs_add_virtual_root(struct jffs_control *c)
-{
-	struct jffs_file *root;
-	struct jffs_node *node;
-
-	D2(printk("jffs_add_virtual_root(): "
-		  "Creating a virtual root directory.\n"));
-
-	if (!(root = kzalloc(sizeof(struct jffs_file), GFP_KERNEL))) {
-		return -ENOMEM;
-	}
-	no_jffs_file++;
-	if (!(node = jffs_alloc_node())) {
-		kfree(root);
-		no_jffs_file--;
-		return -ENOMEM;
-	}
-	DJM(no_jffs_node++);
-	memset(node, 0, sizeof(struct jffs_node));
-	node->ino = JFFS_MIN_INO;
-	root->ino = JFFS_MIN_INO;
-	root->mode = S_IFDIR | S_IRWXU | S_IRGRP
-		     | S_IXGRP | S_IROTH | S_IXOTH;
-	root->atime = root->mtime = root->ctime = get_seconds();
-	root->nlink = 1;
-	root->c = c;
-	root->version_head = root->version_tail = node;
-	jffs_insert_file_into_hash(root);
-	return 0;
-}
-
-
-/* This is where the file system is built and initialized.  */
-int
-jffs_build_fs(struct super_block *sb)
-{
-	struct jffs_control *c;
-	int err = 0;
-
-	D2(printk("jffs_build_fs()\n"));
-
-	if (!(c = jffs_create_control(sb))) {
-		return -ENOMEM;
-	}
-	c->building_fs = 1;
-	c->sb = sb;
-	if ((err = jffs_scan_flash(c)) < 0) {
-		if(err == -EAGAIN){
-			/* scan_flash() wants us to try once more. A flipping 
-			   bits sector was detect in the middle of the scan flash.
-			   Clean up old allocated memory before going in.
-			*/
-			D1(printk("jffs_build_fs: Cleaning up all control structures,"
-				  " reallocating them and trying mount again.\n"));
-			jffs_cleanup_control(c);
-			if (!(c = jffs_create_control(sb))) {
-				return -ENOMEM;
-			}
-			c->building_fs = 1;
-			c->sb = sb;
-
-			if ((err = jffs_scan_flash(c)) < 0) {
-				goto jffs_build_fs_fail;
-			}			
-		}else{
-			goto jffs_build_fs_fail;
-		}
-	}
-
-	/* Add a virtual root node if no one exists.  */
-	if (!jffs_find_file(c, JFFS_MIN_INO)) {
-		if ((err = jffs_add_virtual_root(c)) < 0) {
-			goto jffs_build_fs_fail;
-		}
-	}
-
-	while (c->delete_list) {
-		struct jffs_file *f;
-		struct jffs_delete_list *delete_list_element;
-
-		if ((f = jffs_find_file(c, c->delete_list->ino))) {
-			f->deleted = 1;
-		}
-		delete_list_element = c->delete_list;
-		c->delete_list = c->delete_list->next;
-		kfree(delete_list_element);
-	}
-
-	/* Remove deleted nodes.  */
-	if ((err = jffs_foreach_file(c, jffs_possibly_delete_file)) < 0) {
-		printk(KERN_ERR "JFFS: Failed to remove deleted nodes.\n");
-		goto jffs_build_fs_fail;
-	}
-	/* Remove redundant nodes.  (We are not interested in the
-	   return value in this case.)  */
-	jffs_foreach_file(c, jffs_remove_redundant_nodes);
-	/* Try to build a tree from all the nodes.  */
-	if ((err = jffs_foreach_file(c, jffs_insert_file_into_tree)) < 0) {
-		printk("JFFS: Failed to build tree.\n");
-		goto jffs_build_fs_fail;
-	}
-	/* Compute the sizes of all files in the filesystem.  Adjust if
-	   necessary.  */
-	if ((err = jffs_foreach_file(c, jffs_build_file)) < 0) {
-		printk("JFFS: Failed to build file system.\n");
-		goto jffs_build_fs_fail;
-	}
-	sb->s_fs_info = (void *)c;
-	c->building_fs = 0;
-
-	D1(jffs_print_hash_table(c));
-	D1(jffs_print_tree(c->root, 0));
-
-	return 0;
-
-jffs_build_fs_fail:
-	jffs_cleanup_control(c);
-	return err;
-} /* jffs_build_fs()  */
-
-
-/*
-  This checks for sectors that were being erased in their previous 
-  lifetimes and for some reason or the other (power fail etc.), 
-  the erase cycles never completed.
-  As the flash array would have reverted back to read status, 
-  these sectors are detected by the symptom of the "flipping bits",
-  i.e. bits being read back differently from the same location in
-  flash if read multiple times.
-  The only solution to this is to re-erase the entire
-  sector.
-  Unfortunately detecting "flipping bits" is not a simple exercise
-  as a bit may be read back at 1 or 0 depending on the alignment 
-  of the stars in the universe.
-  The level of confidence is in direct proportion to the number of 
-  scans done. By power fail testing I (Vipin) have been able to 
-  proove that reading twice is not enough.
-  Maybe 4 times? Change NUM_REREADS to a higher number if you want
-  a (even) higher degree of confidence in your mount process. 
-  A higher number would of course slow down your mount.
-*/
-static int check_partly_erased_sectors(struct jffs_fmcontrol *fmc){
-
-#define NUM_REREADS             4 /* see note above */
-#define READ_AHEAD_BYTES        4096 /* must be a multiple of 4, 
-					usually set to kernel page size */
-
-	__u8 *read_buf1;
-	__u8 *read_buf2;
-
-	int err = 0;
-	int retlen;
-	int i;
-	int cnt;
-	__u32 offset;
-	loff_t pos = 0;
-	loff_t end = fmc->flash_size;
-
-
-	/* Allocate read buffers */
-	read_buf1 = kmalloc(sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
-	if (!read_buf1)
-		return -ENOMEM;
-
-	read_buf2 = kmalloc(sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
-	if (!read_buf2) {
-		kfree(read_buf1);
-		return -ENOMEM;
-	}
-
- CHECK_NEXT:
-	while(pos < end){
-		
-		D1(printk("check_partly_erased_sector():checking sector which contains"
-			  " offset 0x%x for flipping bits..\n", (__u32)pos));
-		
-		retlen = flash_safe_read(fmc->mtd, pos,
-					 &read_buf1[0], READ_AHEAD_BYTES);
-		retlen &= ~3;
-		
-		for(cnt = 0; cnt < NUM_REREADS; cnt++){
-			(void)flash_safe_read(fmc->mtd, pos,
-					      &read_buf2[0], READ_AHEAD_BYTES);
-			
-			for (i=0 ; i < retlen ; i+=4) {
-				/* buffers MUST match, double word for word! */
-				if(*((__u32 *) &read_buf1[i]) !=
-				   *((__u32 *) &read_buf2[i])
-				   ){
-				        /* flipping bits detected, time to erase sector */
-					/* This will help us log some statistics etc. */
-					D1(printk("Flipping bits detected in re-read round:%i of %i\n",
-					       cnt, NUM_REREADS));
-					D1(printk("check_partly_erased_sectors:flipping bits detected"
-						  " @offset:0x%x(0x%x!=0x%x)\n",
-						  (__u32)pos+i, *((__u32 *) &read_buf1[i]), 
-						  *((__u32 *) &read_buf2[i])));
-					
-				        /* calculate start of present sector */
-					offset = (((__u32)pos+i)/(__u32)fmc->sector_size) * (__u32)fmc->sector_size;
-					
-					D1(printk("check_partly_erased_sector():erasing sector starting 0x%x.\n",
-						  offset));
-					
-					if (flash_erase_region(fmc->mtd,
-							       offset, fmc->sector_size) < 0) {
-						printk(KERN_ERR "JFFS: Erase of flash failed. "
-						       "offset = %u, erase_size = %d\n",
-						       offset , fmc->sector_size);
-						
-						err = -EIO;
-						goto returnBack;
-
-					}else{
-						D1(printk("JFFS: Erase of flash sector @0x%x successful.\n",
-						       offset));
-						/* skip ahead to the next sector */
-						pos = (((__u32)pos+i)/(__u32)fmc->sector_size) * (__u32)fmc->sector_size;
-						pos += fmc->sector_size;
-						goto CHECK_NEXT;
-					}
-				}
-			}
-		}
-		pos += READ_AHEAD_BYTES;
-	}
-
- returnBack:
-	kfree(read_buf1);
-	kfree(read_buf2);
-
-	D2(printk("check_partly_erased_sector():Done checking all sectors till offset 0x%x for flipping bits.\n",
-		  (__u32)pos));
-
-	return err;
-
-}/* end check_partly_erased_sectors() */
-
-
-
-/* Scan the whole flash memory in order to find all nodes in the
-   file systems.  */
-static int
-jffs_scan_flash(struct jffs_control *c)
-{
-	char name[JFFS_MAX_NAME_LEN + 2];
-	struct jffs_raw_inode raw_inode;
-	struct jffs_node *node = NULL;
-	struct jffs_fmcontrol *fmc = c->fmc;
-	__u32 checksum;
-	__u8 tmp_accurate;
-	__u16 tmp_chksum;
-	__u32 deleted_file;
-	loff_t pos = 0;
-	loff_t start;
-	loff_t test_start;
-	loff_t end = fmc->flash_size;
-	__u8 *read_buf;
-	int i, len, retlen;
-	__u32 offset;
-
-	__u32 free_chunk_size1;
-	__u32 free_chunk_size2;
-
-	
-#define NUMFREEALLOWED     2        /* 2 chunks of at least erase size space allowed */
-	int num_free_space = 0;       /* Flag err if more than TWO
-				       free blocks found. This is NOT allowed
-				       by the current jffs design.
-				    */
-	int num_free_spc_not_accp = 0; /* For debugging purposed keep count 
-					of how much free space was rejected and
-					marked dirty
-				     */
-
-	D1(printk("jffs_scan_flash(): start pos = 0x%lx, end = 0x%lx\n",
-		  (long)pos, (long)end));
-
-	flash_safe_acquire(fmc->mtd);
-
-	/*
-	  check and make sure that any sector does not suffer
-	  from the "partly erased, bit flipping syndrome" (TM Vipin :)
-	  If so, offending sectors will be erased.
-	*/
-	if(check_partly_erased_sectors(fmc) < 0){
-
-		flash_safe_release(fmc->mtd);
-		return -EIO; /* bad, bad, bad error. Cannot continue.*/
-	}
-
-	/* Allocate read buffer */
-	read_buf = kmalloc(sizeof(__u8) * 4096, GFP_KERNEL);
-	if (!read_buf) {
-		flash_safe_release(fmc->mtd);
-		return -ENOMEM;
-	}
-			      
-	/* Start the scan.  */
-	while (pos < end) {
-		deleted_file = 0;
-
-		/* Remember the position from where we started this scan.  */
-		start = pos;
-
-		switch (flash_read_u32(fmc->mtd, pos)) {
-		case JFFS_EMPTY_BITMASK:
-			/* We have found 0xffffffff at this position.  We have to
-			   scan the rest of the flash till the end or till
-			   something else than 0xffffffff is found.
-		           Keep going till we do not find JFFS_EMPTY_BITMASK 
-			   anymore */
-
-			D1(printk("jffs_scan_flash(): 0xffffffff at pos 0x%lx.\n",
-				  (long)pos));
-
-		        while(pos < end){
-
-			      len = end - pos < 4096 ? end - pos : 4096;
-			      
-			      retlen = flash_safe_read(fmc->mtd, pos,
-						 &read_buf[0], len);
-
-			      retlen &= ~3;
-			      
-			      for (i=0 ; i < retlen ; i+=4, pos += 4) {
-				      if(*((__u32 *) &read_buf[i]) !=
-					 JFFS_EMPTY_BITMASK)
-					break;
-			      }
-			      if (i == retlen)
-				    continue;
-			      else
-				    break;
-			}
-
-			D1(printk("jffs_scan_flash():0xffffffff ended at pos 0x%lx.\n",
-				  (long)pos));
-			
-			/* If some free space ends in the middle of a sector,
-			   treat it as dirty rather than clean.
-			   This is to handle the case where one thread 
-			   allocated space for a node, but didn't get to
-			   actually _write_ it before power was lost, leaving
-			   a gap in the log. Shifting all node writes into
-			   a single kernel thread will fix the original problem.
-			*/
-			if ((__u32) pos % fmc->sector_size) {
-				/* If there was free space in previous 
-				   sectors, don't mark that dirty too - 
-				   only from the beginning of this sector
-				   (or from start) 
-				*/
-
-			        test_start = pos & ~(fmc->sector_size-1); /* end of last sector */
-
-				if (start < test_start) {
-
-				        /* free space started in the previous sector! */
-
-					if((num_free_space < NUMFREEALLOWED) && 
-					   ((unsigned int)(test_start - start) >= fmc->sector_size)){
-
-				                /*
-						  Count it in if we are still under NUMFREEALLOWED *and* it is 
-						  at least 1 erase sector in length. This will keep us from 
-						  picking any little ole' space as "free".
-						*/
-					  
-					        D1(printk("Reducing end of free space to 0x%x from 0x%x\n",
-							  (unsigned int)test_start, (unsigned int)pos));
-
-						D1(printk("Free space accepted: Starting 0x%x for 0x%x bytes\n",
-							  (unsigned int) start,
-							  (unsigned int)(test_start - start)));
-
-						/* below, space from "start" to "pos" will be marked dirty. */
-						start = test_start; 
-						
-						/* Being in here means that we have found at least an entire 
-						   erase sector size of free space ending on a sector boundary.
-						   Keep track of free spaces accepted.
-						*/
-						num_free_space++;
-					}else{
-					        num_free_spc_not_accp++;
-					        D1(printk("Free space (#%i) found but *Not* accepted: Starting"
-							  " 0x%x for 0x%x bytes\n",
-							  num_free_spc_not_accp, (unsigned int)start, 
-							  (unsigned int)((unsigned int)(pos & ~(fmc->sector_size-1)) - (unsigned int)start)));
-					        
-					}
-					
-				}
-				if((((__u32)(pos - start)) != 0)){
-
-				        D1(printk("Dirty space: Starting 0x%x for 0x%x bytes\n",
-						  (unsigned int) start, (unsigned int) (pos - start)));
-					jffs_fmalloced(fmc, (__u32) start,
-						       (__u32) (pos - start), NULL);
-				}else{
-					/* "Flipping bits" detected. This means that our scan for them
-					   did not catch this offset. See check_partly_erased_sectors() for
-					   more info.
-					*/
-				        
-					D1(printk("jffs_scan_flash():wants to allocate dirty flash "
-						  "space for 0 bytes.\n"));
-					D1(printk("jffs_scan_flash(): Flipping bits! We will free "
-						  "all allocated memory, erase this sector and remount\n"));
-
-					/* calculate start of present sector */
-					offset = (((__u32)pos)/(__u32)fmc->sector_size) * (__u32)fmc->sector_size;
-					
-					D1(printk("jffs_scan_flash():erasing sector starting 0x%x.\n",
-						  offset));
-					
-					if (flash_erase_region(fmc->mtd,
-							       offset, fmc->sector_size) < 0) {
-						printk(KERN_ERR "JFFS: Erase of flash failed. "
-						       "offset = %u, erase_size = %d\n",
-						       offset , fmc->sector_size);
-
-						flash_safe_release(fmc->mtd);
-						kfree(read_buf);
-						return -1; /* bad, bad, bad! */
-
-					}
-					flash_safe_release(fmc->mtd);
-					kfree(read_buf);
-
-					return -EAGAIN; /* erased offending sector. Try mount one more time please. */
-				}
-			}else{
-			        /* Being in here means that we have found free space that ends on an erase sector
-				   boundary.
-				   Count it in if we are still under NUMFREEALLOWED *and* it is at least 1 erase 
-				   sector in length. This will keep us from picking any little ole' space as "free".
-				 */
-			         if((num_free_space < NUMFREEALLOWED) && 
-				    ((unsigned int)(pos - start) >= fmc->sector_size)){
-				           /* We really don't do anything to mark space as free, except *not* 
-					      mark it dirty and just advance the "pos" location pointer. 
-					      It will automatically be picked up as free space.
-					    */ 
-				           num_free_space++;
-				           D1(printk("Free space accepted: Starting 0x%x for 0x%x bytes\n",
-						     (unsigned int) start, (unsigned int) (pos - start)));
-				 }else{
-				         num_free_spc_not_accp++;
-					 D1(printk("Free space (#%i) found but *Not* accepted: Starting "
-						   "0x%x for 0x%x bytes\n", num_free_spc_not_accp, 
-						   (unsigned int) start, 
-						   (unsigned int) (pos - start)));
-					 
-					 /* Mark this space as dirty. We already have our free space. */
-					 D1(printk("Dirty space: Starting 0x%x for 0x%x bytes\n",
-						   (unsigned int) start, (unsigned int) (pos - start)));
-					 jffs_fmalloced(fmc, (__u32) start,
-							(__u32) (pos - start), NULL);				           
-				 }
-				 
-			}
-			if(num_free_space > NUMFREEALLOWED){
-			         printk(KERN_WARNING "jffs_scan_flash(): Found free space "
-					"number %i. Only %i free space is allowed.\n",
-					num_free_space, NUMFREEALLOWED);			      
-			}
-			continue;
-
-		case JFFS_DIRTY_BITMASK:
-			/* We have found 0x00000000 at this position.  Scan as far
-			   as possible to find out how much is dirty.  */
-			D1(printk("jffs_scan_flash(): 0x00000000 at pos 0x%lx.\n",
-				  (long)pos));
-			for (; pos < end
-			       && JFFS_DIRTY_BITMASK == flash_read_u32(fmc->mtd, pos);
-			     pos += 4);
-			D1(printk("jffs_scan_flash(): 0x00 ended at "
-				  "pos 0x%lx.\n", (long)pos));
-			jffs_fmalloced(fmc, (__u32) start,
-				       (__u32) (pos - start), NULL);
-			continue;
-
-		case JFFS_MAGIC_BITMASK:
-			/* We have probably found a new raw inode.  */
-			break;
-
-		default:
-		bad_inode:
-			/* We're f*cked.  This is not solved yet.  We have
-			   to scan for the magic pattern.  */
-			D1(printk("*************** Dirty flash memory or "
-				  "bad inode: "
-				  "hexdump(pos = 0x%lx, len = 128):\n",
-				  (long)pos));
-			D1(jffs_hexdump(fmc->mtd, pos, 128));
-
-			for (pos += 4; pos < end; pos += 4) {
-				switch (flash_read_u32(fmc->mtd, pos)) {
-				case JFFS_MAGIC_BITMASK:
-				case JFFS_EMPTY_BITMASK:
-					/* handle these in the main switch() loop */
-					goto cont_scan;
-
-				default:
-					break;
-				}
-			}
-
-			cont_scan:
-			/* First, mark as dirty the region
-			   which really does contain crap. */
-			jffs_fmalloced(fmc, (__u32) start,
-				       (__u32) (pos - start),
-				       NULL);
-			
-			continue;
-		}/* switch */
-
-		/* We have found the beginning of an inode.  Create a
-		   node for it unless there already is one available.  */
-		if (!node) {
-			if (!(node = jffs_alloc_node())) {
-				/* Free read buffer */
-				kfree(read_buf);
-
-				/* Release the flash device */
-				flash_safe_release(fmc->mtd);
-	
-				return -ENOMEM;
-			}
-			DJM(no_jffs_node++);
-		}
-
-		/* Read the next raw inode.  */
-
-		flash_safe_read(fmc->mtd, pos, (u_char *) &raw_inode,
-				sizeof(struct jffs_raw_inode));
-
-		/* When we compute the checksum for the inode, we never
-		   count the 'accurate' or the 'checksum' fields.  */
-		tmp_accurate = raw_inode.accurate;
-		tmp_chksum = raw_inode.chksum;
-		raw_inode.accurate = 0;
-		raw_inode.chksum = 0;
-		checksum = jffs_checksum(&raw_inode,
-					 sizeof(struct jffs_raw_inode));
-		raw_inode.accurate = tmp_accurate;
-		raw_inode.chksum = tmp_chksum;
-
-		D3(printk("*** We have found this raw inode at pos 0x%lx "
-			  "on the flash:\n", (long)pos));
-		D3(jffs_print_raw_inode(&raw_inode));
-
-		if (checksum != raw_inode.chksum) {
-			D1(printk("jffs_scan_flash(): Bad checksum: "
-				  "checksum = %u, "
-				  "raw_inode.chksum = %u\n",
-				  checksum, raw_inode.chksum));
-			pos += sizeof(struct jffs_raw_inode);
-			jffs_fmalloced(fmc, (__u32) start,
-				       (__u32) (pos - start), NULL);
-			/* Reuse this unused struct jffs_node.  */
-			continue;
-		}
-
-		/* Check the raw inode read so far.  Start with the
-		   maximum length of the filename.  */
-		if (raw_inode.nsize > JFFS_MAX_NAME_LEN) {
-			printk(KERN_WARNING "jffs_scan_flash: Found a "
-			       "JFFS node with name too large\n");
-			goto bad_inode;
-		}
-
-		if (raw_inode.rename && raw_inode.dsize != sizeof(__u32)) {
-			printk(KERN_WARNING "jffs_scan_flash: Found a "
-			       "rename node with dsize %u.\n",
-			       raw_inode.dsize);
-			jffs_print_raw_inode(&raw_inode);
-			goto bad_inode;
-		}
-
-		/* The node's data segment should not exceed a
-		   certain length.  */
-		if (raw_inode.dsize > fmc->max_chunk_size) {
-			printk(KERN_WARNING "jffs_scan_flash: Found a "
-			       "JFFS node with dsize (0x%x) > max_chunk_size (0x%x)\n",
-			       raw_inode.dsize, fmc->max_chunk_size);
-			goto bad_inode;
-		}
-
-		pos += sizeof(struct jffs_raw_inode);
-
-		/* This shouldn't be necessary because a node that
-		   violates the flash boundaries shouldn't be written
-		   in the first place. */
-		if (pos >= end) {
-			goto check_node;
-		}
-
-		/* Read the name.  */
-		*name = 0;
-		if (raw_inode.nsize) {
-		        flash_safe_read(fmc->mtd, pos, name, raw_inode.nsize);
-			name[raw_inode.nsize] = '\0';
-			pos += raw_inode.nsize
-			       + JFFS_GET_PAD_BYTES(raw_inode.nsize);
-			D3(printk("name == \"%s\"\n", name));
-			checksum = jffs_checksum(name, raw_inode.nsize);
-			if (checksum != raw_inode.nchksum) {
-				D1(printk("jffs_scan_flash(): Bad checksum: "
-					  "checksum = %u, "
-					  "raw_inode.nchksum = %u\n",
-					  checksum, raw_inode.nchksum));
-				jffs_fmalloced(fmc, (__u32) start,
-					       (__u32) (pos - start), NULL);
-				/* Reuse this unused struct jffs_node.  */
-				continue;
-			}
-			if (pos >= end) {
-				goto check_node;
-			}
-		}
-
-		/* Read the data, if it exists, in order to be sure it
-		   matches the checksum.  */
-		if (raw_inode.dsize) {
-			if (raw_inode.rename) {
-				deleted_file = flash_read_u32(fmc->mtd, pos);
-			}
-			if (jffs_checksum_flash(fmc->mtd, pos, raw_inode.dsize, &checksum)) {
-				printk("jffs_checksum_flash() failed to calculate a checksum\n");
-				jffs_fmalloced(fmc, (__u32) start,
-					       (__u32) (pos - start), NULL);
-				/* Reuse this unused struct jffs_node.  */
-				continue;
-			}				
-			pos += raw_inode.dsize
-			       + JFFS_GET_PAD_BYTES(raw_inode.dsize);
-
-			if (checksum != raw_inode.dchksum) {
-				D1(printk("jffs_scan_flash(): Bad checksum: "
-					  "checksum = %u, "
-					  "raw_inode.dchksum = %u\n",
-					  checksum, raw_inode.dchksum));
-				jffs_fmalloced(fmc, (__u32) start,
-					       (__u32) (pos - start), NULL);
-				/* Reuse this unused struct jffs_node.  */
-				continue;
-			}
-		}
-
-		check_node:
-
-		/* Remember the highest inode number in the whole file
-		   system.  This information will be used when assigning
-		   new files new inode numbers.  */
-		if (c->next_ino <= raw_inode.ino) {
-			c->next_ino = raw_inode.ino + 1;
-		}
-
-		if (raw_inode.accurate) {
-			int err;
-			node->data_offset = raw_inode.offset;
-			node->data_size = raw_inode.dsize;
-			node->removed_size = raw_inode.rsize;
-			/* Compute the offset to the actual data in the
-			   on-flash node.  */
-			node->fm_offset
-			= sizeof(struct jffs_raw_inode)
-			  + raw_inode.nsize
-			  + JFFS_GET_PAD_BYTES(raw_inode.nsize);
-			node->fm = jffs_fmalloced(fmc, (__u32) start,
-						  (__u32) (pos - start),
-						  node);
-			if (!node->fm) {
-				D(printk("jffs_scan_flash(): !node->fm\n"));
-				jffs_free_node(node);
-				DJM(no_jffs_node--);
-
-				/* Free read buffer */
-				kfree(read_buf);
-
-				/* Release the flash device */
-				flash_safe_release(fmc->mtd);
-
-				return -ENOMEM;
-			}
-			if ((err = jffs_insert_node(c, NULL, &raw_inode,
-						    name, node)) < 0) {
-				printk("JFFS: Failed to handle raw inode. "
-				       "(err = %d)\n", err);
-				break;
-			}
-			if (raw_inode.rename) {
-				struct jffs_delete_list *dl
-				= (struct jffs_delete_list *)
-				  kmalloc(sizeof(struct jffs_delete_list),
-					  GFP_KERNEL);
-				if (!dl) {
-					D(printk("jffs_scan_flash: !dl\n"));
-					jffs_free_node(node);
-					DJM(no_jffs_node--);
-
-					/* Release the flash device */
-					flash_safe_release(fmc->flash_part);
-
-					/* Free read buffer */
-					kfree(read_buf);
-
-					return -ENOMEM;
-				}
-				dl->ino = deleted_file;
-				dl->next = c->delete_list;
-				c->delete_list = dl;
-				node->data_size = 0;
-			}
-			D3(jffs_print_node(node));
-			node = NULL; /* Don't free the node!  */
-		}
-		else {
-			jffs_fmalloced(fmc, (__u32) start,
-				       (__u32) (pos - start), NULL);
-			D3(printk("jffs_scan_flash(): Just found an obsolete "
-				  "raw_inode. Continuing the scan...\n"));
-			/* Reuse this unused struct jffs_node.  */
-		}
-	}
-
-	if (node) {
-		jffs_free_node(node);
-		DJM(no_jffs_node--);
-	}
-	jffs_build_end(fmc);
-
-	/* Free read buffer */
-	kfree(read_buf);
-
-	if(!num_free_space){
-	        printk(KERN_WARNING "jffs_scan_flash(): Did not find even a single "
-		       "chunk of free space. This is BAD!\n");
-	}
-
-	/* Return happy */
-	D3(printk("jffs_scan_flash(): Leaving...\n"));
-	flash_safe_release(fmc->mtd);
-
-	/* This is to trap the "free size accounting screwed error. */
-	free_chunk_size1 = jffs_free_size1(fmc);
-	free_chunk_size2 = jffs_free_size2(fmc);
-
-	if (free_chunk_size1 + free_chunk_size2 != fmc->free_size) {
-
-		printk(KERN_WARNING "jffs_scan_falsh():Free size accounting screwed\n");
-		printk(KERN_WARNING "jfffs_scan_flash():free_chunk_size1 == 0x%x, "
-		       "free_chunk_size2 == 0x%x, fmc->free_size == 0x%x\n", 
-		       free_chunk_size1, free_chunk_size2, fmc->free_size);
-
-		return -1; /* Do NOT mount f/s so that we can inspect what happened.
-			      Mounting this  screwed up f/s will screw us up anyway.
-			    */
-	}	
-
-	return 0; /* as far as we are concerned, we are happy! */
-} /* jffs_scan_flash()  */
-
-
-/* Insert any kind of node into the file system.  Take care of data
-   insertions and deletions.  Also remove redundant information. The
-   memory allocated for the `name' is regarded as "given away" in the
-   caller's perspective.  */
-int
-jffs_insert_node(struct jffs_control *c, struct jffs_file *f,
-		 const struct jffs_raw_inode *raw_inode,
-		 const char *name, struct jffs_node *node)
-{
-	int update_name = 0;
-	int insert_into_tree = 0;
-
-	D2(printk("jffs_insert_node(): ino = %u, version = %u, "
-		  "name = \"%s\", deleted = %d\n",
-		  raw_inode->ino, raw_inode->version,
-		  ((name && *name) ? name : ""), raw_inode->deleted));
-
-	/* If there doesn't exist an associated jffs_file, then
-	   create, initialize and insert one into the file system.  */
-	if (!f && !(f = jffs_find_file(c, raw_inode->ino))) {
-		if (!(f = jffs_create_file(c, raw_inode))) {
-			return -ENOMEM;
-		}
-		jffs_insert_file_into_hash(f);
-		insert_into_tree = 1;
-	}
-	node->ino = raw_inode->ino;
-	node->version = raw_inode->version;
-	node->data_size = raw_inode->dsize;
-	node->fm_offset = sizeof(struct jffs_raw_inode) + raw_inode->nsize
-			  + JFFS_GET_PAD_BYTES(raw_inode->nsize);
-	node->name_size = raw_inode->nsize;
-
-	/* Now insert the node at the correct position into the file's
-	   version list.  */
-	if (!f->version_head) {
-		/* This is the first node.  */
-		f->version_head = node;
-		f->version_tail = node;
-		node->version_prev = NULL;
-		node->version_next = NULL;
-		f->highest_version = node->version;
-		update_name = 1;
-		f->mode = raw_inode->mode;
-		f->uid = raw_inode->uid;
-		f->gid = raw_inode->gid;
-		f->atime = raw_inode->atime;
-		f->mtime = raw_inode->mtime;
-		f->ctime = raw_inode->ctime;
-	}
-	else if ((f->highest_version < node->version)
-		 || (node->version == 0)) {
-		/* Insert at the end of the list.  I.e. this node is the
-		   newest one so far.  */
-		node->version_prev = f->version_tail;
-		node->version_next = NULL;
-		f->version_tail->version_next = node;
-		f->version_tail = node;
-		f->highest_version = node->version;
-		update_name = 1;
-		f->pino = raw_inode->pino;
-		f->mode = raw_inode->mode;
-		f->uid = raw_inode->uid;
-		f->gid = raw_inode->gid;
-		f->atime = raw_inode->atime;
-		f->mtime = raw_inode->mtime;
-		f->ctime = raw_inode->ctime;
-	}
-	else if (f->version_head->version > node->version) {
-		/* Insert at the bottom of the list.  */
-		node->version_prev = NULL;
-		node->version_next = f->version_head;
-		f->version_head->version_prev = node;
-		f->version_head = node;
-		if (!f->name) {
-			update_name = 1;
-		}
-	}
-	else {
-		struct jffs_node *n;
-		int newer_name = 0;
-		/* Search for the insertion position starting from
-		   the tail (newest node).  */
-		for (n = f->version_tail; n; n = n->version_prev) {
-			if (n->version < node->version) {
-				node->version_prev = n;
-				node->version_next = n->version_next;
-				node->version_next->version_prev = node;
-				n->version_next = node;
-				if (!newer_name) {
-					update_name = 1;
-				}
-				break;
-			}
-			if (n->name_size) {
-				newer_name = 1;
-			}
-		}
-	}
-
-	/* Deletion is irreversible. If any 'deleted' node is ever
-	   written, the file is deleted */
-	if (raw_inode->deleted)
-		f->deleted = raw_inode->deleted;
-
-	/* Perhaps update the name.  */
-	if (raw_inode->nsize && update_name && name && *name && (name != f->name)) {
-		if (f->name) {
-			kfree(f->name);
-			DJM(no_name--);
-		}
-		if (!(f->name = kmalloc(raw_inode->nsize + 1,
-						 GFP_KERNEL))) {
-			return -ENOMEM;
-		}
-		DJM(no_name++);
-		memcpy(f->name, name, raw_inode->nsize);
-		f->name[raw_inode->nsize] = '\0';
-		f->nsize = raw_inode->nsize;
-		D3(printk("jffs_insert_node(): Updated the name of "
-			  "the file to \"%s\".\n", name));
-	}
-
-	if (!c->building_fs) {
-		D3(printk("jffs_insert_node(): ---------------------------"
-			  "------------------------------------------- 1\n"));
-		if (insert_into_tree) {
-			jffs_insert_file_into_tree(f);
-		}
-		/* Once upon a time, we would call jffs_possibly_delete_file()
-		   here. That causes an oops if someone's still got the file
-		   open, so now we only do it in jffs_delete_inode()
-		   -- dwmw2
-		*/
-		if (node->data_size || node->removed_size) {
-			jffs_update_file(f, node);
-		}
-		jffs_remove_redundant_nodes(f);
-
-		jffs_garbage_collect_trigger(c);
-
-		D3(printk("jffs_insert_node(): ---------------------------"
-			  "------------------------------------------- 2\n"));
-	}
-
-	return 0;
-} /* jffs_insert_node()  */
-
-
-/* Unlink a jffs_node from the version list it is in.  */
-static inline void
-jffs_unlink_node_from_version_list(struct jffs_file *f,
-				   struct jffs_node *node)
-{
-	if (node->version_prev) {
-		node->version_prev->version_next = node->version_next;
-	} else {
-		f->version_head = node->version_next;
-	}
-	if (node->version_next) {
-		node->version_next->version_prev = node->version_prev;
-	} else {
-		f->version_tail = node->version_prev;
-	}
-}
-
-
-/* Unlink a jffs_node from the range list it is in.  */
-static inline void
-jffs_unlink_node_from_range_list(struct jffs_file *f, struct jffs_node *node)
-{
-	if (node->range_prev) {
-		node->range_prev->range_next = node->range_next;
-	}
-	else {
-		f->range_head = node->range_next;
-	}
-	if (node->range_next) {
-		node->range_next->range_prev = node->range_prev;
-	}
-	else {
-		f->range_tail = node->range_prev;
-	}
-}
-
-
-/* Function used by jffs_remove_redundant_nodes() below.  This function
-   classifies what kind of information a node adds to a file.  */
-static inline __u8
-jffs_classify_node(struct jffs_node *node)
-{
-	__u8 mod_type = JFFS_MODIFY_INODE;
-
-	if (node->name_size) {
-		mod_type |= JFFS_MODIFY_NAME;
-	}
-	if (node->data_size || node->removed_size) {
-		mod_type |= JFFS_MODIFY_DATA;
-	}
-	return mod_type;
-}
-
-
-/* Remove redundant nodes from a file.  Mark the on-flash memory
-   as dirty.  */
-static int
-jffs_remove_redundant_nodes(struct jffs_file *f)
-{
-	struct jffs_node *newest_node;
-	struct jffs_node *cur;
-	struct jffs_node *prev;
-	__u8 newest_type;
-	__u8 mod_type;
-	__u8 node_with_name_later = 0;
-
-	if (!(newest_node = f->version_tail)) {
-		return 0;
-	}
-
-	/* What does the `newest_node' modify?  */
-	newest_type = jffs_classify_node(newest_node);
-	node_with_name_later = newest_type & JFFS_MODIFY_NAME;
-
-	D3(printk("jffs_remove_redundant_nodes(): ino: %u, name: \"%s\", "
-		  "newest_type: %u\n", f->ino, (f->name ? f->name : ""),
-		  newest_type));
-
-	/* Traverse the file's nodes and determine which of them that are
-	   superfluous.  Yeah, this might look very complex at first
-	   glance but it is actually very simple.  */
-	for (cur = newest_node->version_prev; cur; cur = prev) {
-		prev = cur->version_prev;
-		mod_type = jffs_classify_node(cur);
-		if ((mod_type <= JFFS_MODIFY_INODE)
-		    || ((newest_type & JFFS_MODIFY_NAME)
-			&& (mod_type
-			    <= (JFFS_MODIFY_INODE + JFFS_MODIFY_NAME)))
-		    || (cur->data_size == 0 && cur->removed_size
-			&& !cur->version_prev && node_with_name_later)) {
-			/* Yes, this node is redundant. Remove it.  */
-			D2(printk("jffs_remove_redundant_nodes(): "
-				  "Removing node: ino: %u, version: %u, "
-				  "mod_type: %u\n", cur->ino, cur->version,
-				  mod_type));
-			jffs_unlink_node_from_version_list(f, cur);
-			jffs_fmfree(f->c->fmc, cur->fm, cur);
-			jffs_free_node(cur);
-			DJM(no_jffs_node--);
-		}
-		else {
-			node_with_name_later |= (mod_type & JFFS_MODIFY_NAME);
-		}
-	}
-
-	return 0;
-}
-
-
-/* Insert a file into the hash table.  */
-static int
-jffs_insert_file_into_hash(struct jffs_file *f)
-{
-	int i = f->ino % f->c->hash_len;
-
-	D3(printk("jffs_insert_file_into_hash(): f->ino: %u\n", f->ino));
-
-	list_add(&f->hash, &f->c->hash[i]);
-	return 0;
-}
-
-
-/* Insert a file into the file system tree.  */
-int
-jffs_insert_file_into_tree(struct jffs_file *f)
-{
-	struct jffs_file *parent;
-
-	D3(printk("jffs_insert_file_into_tree(): name: \"%s\"\n",
-		  (f->name ? f->name : "")));
-
-	if (!(parent = jffs_find_file(f->c, f->pino))) {
-		if (f->pino == 0) {
-			f->c->root = f;
-			f->parent = NULL;
-			f->sibling_prev = NULL;
-			f->sibling_next = NULL;
-			return 0;
-		}
-		else {
-			D1(printk("jffs_insert_file_into_tree(): Found "
-				  "inode with no parent and pino == %u\n",
-				  f->pino));
-			return -1;
-		}
-	}
-	f->parent = parent;
-	f->sibling_next = parent->children;
-	if (f->sibling_next) {
-		f->sibling_next->sibling_prev = f;
-	}
-	f->sibling_prev = NULL;
-	parent->children = f;
-	return 0;
-}
-
-
-/* Remove a file from the hash table.  */
-static int
-jffs_unlink_file_from_hash(struct jffs_file *f)
-{
-	D3(printk("jffs_unlink_file_from_hash(): f: 0x%p, "
-		  "ino %u\n", f, f->ino));
-
-	list_del(&f->hash);
-	return 0;
-}
-
-
-/* Just remove the file from the parent's children.  Don't free
-   any memory.  */
-int
-jffs_unlink_file_from_tree(struct jffs_file *f)
-{
-	D3(printk("jffs_unlink_file_from_tree(): ino: %d, pino: %d, name: "
-		  "\"%s\"\n", f->ino, f->pino, (f->name ? f->name : "")));
-
-	if (f->sibling_prev) {
-		f->sibling_prev->sibling_next = f->sibling_next;
-	}
-	else if (f->parent) {
-	        D3(printk("f->parent=%p\n", f->parent));
-		f->parent->children = f->sibling_next;
-	}
-	if (f->sibling_next) {
-		f->sibling_next->sibling_prev = f->sibling_prev;
-	}
-	return 0;
-}
-
-
-/* Find a file with its inode number.  */
-struct jffs_file *
-jffs_find_file(struct jffs_control *c, __u32 ino)
-{
-	struct jffs_file *f;
-	int i = ino % c->hash_len;
-
-	D3(printk("jffs_find_file(): ino: %u\n", ino));
-
-	list_for_each_entry(f, &c->hash[i], hash) {
-		if (ino != f->ino)
-			continue;
-		D3(printk("jffs_find_file(): Found file with ino "
-			       "%u. (name: \"%s\")\n",
-			       ino, (f->name ? f->name : ""));
-		);
-		return f;
-	}
-	D3(printk("jffs_find_file(): Didn't find file "
-			 "with ino %u.\n", ino);
-	);
-	return NULL;
-}
-
-
-/* Find a file in a directory.  We are comparing the names.  */
-struct jffs_file *
-jffs_find_child(struct jffs_file *dir, const char *name, int len)
-{
-	struct jffs_file *f;
-
-	D3(printk("jffs_find_child()\n"));
-
-	for (f = dir->children; f; f = f->sibling_next) {
-		if (!f->deleted && f->name
-		    && !strncmp(f->name, name, len)
-		    && f->name[len] == '\0') {
-			break;
-		}
-	}
-
-	D3(if (f) {
-		printk("jffs_find_child(): Found \"%s\".\n", f->name);
-	}
-	else {
-		char *copy = kmalloc(len + 1, GFP_KERNEL);
-		if (copy) {
-			memcpy(copy, name, len);
-			copy[len] = '\0';
-		}
-		printk("jffs_find_child(): Didn't find the file \"%s\".\n",
-		       (copy ? copy : ""));
-		kfree(copy);
-	});
-
-	return f;
-}
-
-
-/* Write a raw inode that takes up a certain amount of space in the flash
-   memory.  At the end of the flash device, there is often space that is
-   impossible to use.  At these times we want to mark this space as not
-   used.  In the cases when the amount of space is greater or equal than
-   a struct jffs_raw_inode, we write a "dummy node" that takes up this
-   space.  The space after the raw inode, if it exists, is left as it is.
-   Since this space after the raw inode contains JFFS_EMPTY_BITMASK bytes,
-   we can compute the checksum of it; we don't have to manipulate it any
-   further.
-
-   If the space left on the device is less than the size of a struct
-   jffs_raw_inode, this space is filled with JFFS_DIRTY_BITMASK bytes.
-   No raw inode is written this time.  */
-static int
-jffs_write_dummy_node(struct jffs_control *c, struct jffs_fm *dirty_fm)
-{
-	struct jffs_fmcontrol *fmc = c->fmc;
-	int err;
-
-	D1(printk("jffs_write_dummy_node(): dirty_fm->offset = 0x%08x, "
-		  "dirty_fm->size = %u\n",
-		  dirty_fm->offset, dirty_fm->size));
-
-	if (dirty_fm->size >= sizeof(struct jffs_raw_inode)) {
-		struct jffs_raw_inode raw_inode;
-		memset(&raw_inode, 0, sizeof(struct jffs_raw_inode));
-		raw_inode.magic = JFFS_MAGIC_BITMASK;
-		raw_inode.dsize = dirty_fm->size
-				  - sizeof(struct jffs_raw_inode);
-		raw_inode.dchksum = raw_inode.dsize * 0xff;
-		raw_inode.chksum
-		= jffs_checksum(&raw_inode, sizeof(struct jffs_raw_inode));
-
-		if ((err = flash_safe_write(fmc->mtd,
-					    dirty_fm->offset,
-					    (u_char *)&raw_inode,
-					    sizeof(struct jffs_raw_inode)))
-		    < 0) {
-			printk(KERN_ERR "JFFS: jffs_write_dummy_node: "
-			       "flash_safe_write failed!\n");
-			return err;
-		}
-	}
-	else {
-		flash_safe_acquire(fmc->mtd);
-		flash_memset(fmc->mtd, dirty_fm->offset, 0, dirty_fm->size);
-		flash_safe_release(fmc->mtd);
-	}
-
-	D3(printk("jffs_write_dummy_node(): Leaving...\n"));
-	return 0;
-}
-
-
-/* Write a raw inode, possibly its name and possibly some data.  */
-int
-jffs_write_node(struct jffs_control *c, struct jffs_node *node,
-		struct jffs_raw_inode *raw_inode,
-		const char *name, const unsigned char *data,
-		int recoverable,
-		struct jffs_file *f)
-{
-	struct jffs_fmcontrol *fmc = c->fmc;
-	struct jffs_fm *fm;
-	struct kvec node_iovec[4];
-	unsigned long iovec_cnt;
-
-	__u32 pos;
-	int err;
-	__u32 slack = 0;
-
-	__u32 total_name_size = raw_inode->nsize
-				+ JFFS_GET_PAD_BYTES(raw_inode->nsize);
-	__u32 total_data_size = raw_inode->dsize
-				+ JFFS_GET_PAD_BYTES(raw_inode->dsize);
-	__u32 total_size = sizeof(struct jffs_raw_inode)
-			   + total_name_size + total_data_size;
-	
-	/* If this node isn't something that will eventually let
-	   GC free even more space, then don't allow it unless
-	   there's at least max_chunk_size space still available
-	*/
-	if (!recoverable)
-		slack = fmc->max_chunk_size;
-		
-
-	/* Fire the retrorockets and shoot the fruiton torpedoes, sir!  */
-
-	ASSERT(if (!node) {
-		printk("jffs_write_node(): node == NULL\n");
-		return -EINVAL;
-	});
-	ASSERT(if (raw_inode && raw_inode->nsize && !name) {
-		printk("*** jffs_write_node(): nsize = %u but name == NULL\n",
-		       raw_inode->nsize);
-		return -EINVAL;
-	});
-
-	D1(printk("jffs_write_node(): filename = \"%s\", ino = %u, "
-		  "total_size = %u\n",
-		  (name ? name : ""), raw_inode->ino,
-		  total_size));
-
-	jffs_fm_write_lock(fmc);
-
-retry:
-	fm = NULL;
-	err = 0;
-	while (!fm) {
-
-		/* Deadlocks suck. */
-		while(fmc->free_size < fmc->min_free_size + total_size + slack) {
-			jffs_fm_write_unlock(fmc);
-			if (!JFFS_ENOUGH_SPACE(c, total_size + slack))
-				return -ENOSPC;
-			jffs_fm_write_lock(fmc);
-		}
-
-		/* First try to allocate some flash memory.  */
-		err = jffs_fmalloc(fmc, total_size, node, &fm);
-		
-		if (err == -ENOSPC) {
-			/* Just out of space. GC and try again */
-			if (fmc->dirty_size < fmc->sector_size) {
-				D(printk("jffs_write_node(): jffs_fmalloc(0x%p, %u) "
-					 "failed, no dirty space to GC\n", fmc,
-					 total_size));
-				return err;
-			}
-			
-			D1(printk(KERN_INFO "jffs_write_node(): Calling jffs_garbage_collect_now()\n"));
-			jffs_fm_write_unlock(fmc);
-			if ((err = jffs_garbage_collect_now(c))) {
-				D(printk("jffs_write_node(): jffs_garbage_collect_now() failed\n"));
-				return err;
-			}
-			jffs_fm_write_lock(fmc);
-			continue;
-		} 
-
-		if (err < 0) {
-			jffs_fm_write_unlock(fmc);
-
-			D(printk("jffs_write_node(): jffs_fmalloc(0x%p, %u) "
-				 "failed!\n", fmc, total_size));
-			return err;
-		}
-
-		if (!fm->nodes) {
-			/* The jffs_fm struct that we got is not good enough.
-			   Make that space dirty and try again  */
-			if ((err = jffs_write_dummy_node(c, fm)) < 0) {
-				kfree(fm);
-				DJM(no_jffs_fm--);
-				jffs_fm_write_unlock(fmc);
-				D(printk("jffs_write_node(): "
-					 "jffs_write_dummy_node(): Failed!\n"));
-				return err;
-			}
-			fm = NULL;
-		}
-	} /* while(!fm) */
-	node->fm = fm;
-
-	ASSERT(if (fm->nodes == 0) {
-		printk(KERN_ERR "jffs_write_node(): fm->nodes == 0\n");
-	});
-
-	pos = node->fm->offset;
-
-	/* Increment the version number here. We can't let the caller
-	   set it beforehand, because we might have had to do GC on a node
-	   of this file - and we'd end up reusing version numbers.
-	*/
-	if (f) {
-		raw_inode->version = f->highest_version + 1;
-		D1(printk (KERN_NOTICE "jffs_write_node(): setting version of %s to %d\n", f->name, raw_inode->version));
-
-		/* if the file was deleted, set the deleted bit in the raw inode */
-		if (f->deleted)
-			raw_inode->deleted = 1;
-	}
-
-	/* Compute the checksum for the data and name chunks.  */
-	raw_inode->dchksum = jffs_checksum(data, raw_inode->dsize);
-	raw_inode->nchksum = jffs_checksum(name, raw_inode->nsize);
-
-	/* The checksum is calculated without the chksum and accurate
-	   fields so set them to zero first.  */
-	raw_inode->accurate = 0;
-	raw_inode->chksum = 0;
-	raw_inode->chksum = jffs_checksum(raw_inode,
-					  sizeof(struct jffs_raw_inode));
-	raw_inode->accurate = 0xff;
-
-	D3(printk("jffs_write_node(): About to write this raw inode to the "
-		  "flash at pos 0x%lx:\n", (long)pos));
-	D3(jffs_print_raw_inode(raw_inode));
-
-	/* The actual raw JFFS node */
-	node_iovec[0].iov_base = (void *) raw_inode;
-	node_iovec[0].iov_len = (size_t) sizeof(struct jffs_raw_inode);
-	iovec_cnt = 1;
-
-	/* Get name and size if there is one */
-	if (raw_inode->nsize) {
-		node_iovec[iovec_cnt].iov_base = (void *) name;
-		node_iovec[iovec_cnt].iov_len = (size_t) raw_inode->nsize;
-		iovec_cnt++;
-
-		if (JFFS_GET_PAD_BYTES(raw_inode->nsize)) {
-			static unsigned char allff[3]={255,255,255};
-			/* Add some extra padding if necessary */
-			node_iovec[iovec_cnt].iov_base = allff;
-			node_iovec[iovec_cnt].iov_len =
-				JFFS_GET_PAD_BYTES(raw_inode->nsize);
-			iovec_cnt++;
-		}
-	}
-
-	/* Get data and size if there is any */
-	if (raw_inode->dsize) {
-		node_iovec[iovec_cnt].iov_base = (void *) data;
-		node_iovec[iovec_cnt].iov_len = (size_t) raw_inode->dsize;
-		iovec_cnt++;
-		/* No need to pad this because we're not actually putting
-		   anything after it.
-		*/
-	}
-
-	if ((err = flash_safe_writev(fmc->mtd, node_iovec, iovec_cnt,
-				    pos)) < 0) {
-		jffs_fmfree_partly(fmc, fm, 0);
-		jffs_fm_write_unlock(fmc);
-		printk(KERN_ERR "JFFS: jffs_write_node: Failed to write, "
-		       "requested %i, wrote %i\n", total_size, err);
-		goto retry;
-	}
-	if (raw_inode->deleted)
-		f->deleted = 1;
-
-	jffs_fm_write_unlock(fmc);
-	D3(printk("jffs_write_node(): Leaving...\n"));
-	return raw_inode->dsize;
-} /* jffs_write_node()  */
-
-
-/* Read data from the node and write it to the buffer.  'node_offset'
-   is how much we have read from this particular node before and which
-   shouldn't be read again.  'max_size' is how much space there is in
-   the buffer.  */
-static int
-jffs_get_node_data(struct jffs_file *f, struct jffs_node *node, 
-		   unsigned char *buf,__u32 node_offset, __u32 max_size)
-{
-	struct jffs_fmcontrol *fmc = f->c->fmc;
-	__u32 pos = node->fm->offset + node->fm_offset + node_offset;
-	__u32 avail = node->data_size - node_offset;
-	__u32 r;
-
-	D2(printk("  jffs_get_node_data(): file: \"%s\", ino: %u, "
-		  "version: %u, node_offset: %u\n",
-		  f->name, node->ino, node->version, node_offset));
-
-	r = min(avail, max_size);
-	D3(printk(KERN_NOTICE "jffs_get_node_data\n"));
-	flash_safe_read(fmc->mtd, pos, buf, r);
-
-	D3(printk("  jffs_get_node_data(): Read %u byte%s.\n",
-		  r, (r == 1 ? "" : "s")));
-
-	return r;
-}
-
-
-/* Read data from the file's nodes.  Write the data to the buffer
-   'buf'.  'read_offset' tells how much data we should skip.  */
-int
-jffs_read_data(struct jffs_file *f, unsigned char *buf, __u32 read_offset,
-	       __u32 size)
-{
-	struct jffs_node *node;
-	__u32 read_data = 0; /* Total amount of read data.  */
-	__u32 node_offset = 0;
-	__u32 pos = 0; /* Number of bytes traversed.  */
-
-	D2(printk("jffs_read_data(): file = \"%s\", read_offset = %d, "
-		  "size = %u\n",
-		  (f->name ? f->name : ""), read_offset, size));
-
-	if (read_offset >= f->size) {
-		D(printk("  f->size: %d\n", f->size));
-		return 0;
-	}
-
-	/* First find the node to read data from.  */
-	node = f->range_head;
-	while (pos <= read_offset) {
-		node_offset = read_offset - pos;
-		if (node_offset >= node->data_size) {
-			pos += node->data_size;
-			node = node->range_next;
-		}
-		else {
-			break;
-		}
-	}
-
-	/* "Cats are living proof that not everything in nature
-	   has to be useful."
-	   - Garrison Keilor ('97)  */
-
-	/* Fill the buffer.  */
-	while (node && (read_data < size)) {
-		int r;
-		if (!node->fm) {
-			/* This node does not refer to real data.  */
-			r = min(size - read_data,
-				     node->data_size - node_offset);
-			memset(&buf[read_data], 0, r);
-		}
-		else if ((r = jffs_get_node_data(f, node, &buf[read_data],
-						 node_offset,
-						 size - read_data)) < 0) {
-			return r;
-		}
-		read_data += r;
-		node_offset = 0;
-		node = node->range_next;
-	}
-	D3(printk("  jffs_read_data(): Read %u bytes.\n", read_data));
-	return read_data;
-}
-
-
-/* Used for traversing all nodes in the hash table.  */
-int
-jffs_foreach_file(struct jffs_control *c, int (*func)(struct jffs_file *))
-{
-	int pos;
-	int r;
-	int result = 0;
-
-	for (pos = 0; pos < c->hash_len; pos++) {
-		struct jffs_file *f, *next;
-
-		/* We must do _safe, because 'func' might remove the
-		   current file 'f' from the list.  */
-		list_for_each_entry_safe(f, next, &c->hash[pos], hash) {
-			r = func(f);
-			if (r < 0)
-				return r;
-			result += r;
-		}
-	}
-
-	return result;
-}
-
-
-/* Free all nodes associated with a file.  */
-static int
-jffs_free_node_list(struct jffs_file *f)
-{
-	struct jffs_node *node;
-	struct jffs_node *p;
-
-	D3(printk("jffs_free_node_list(): f #%u, \"%s\"\n",
-		  f->ino, (f->name ? f->name : "")));
-	node = f->version_head;
-	while (node) {
-		p = node;
-		node = node->version_next;
-		jffs_free_node(p);
-		DJM(no_jffs_node--);
-	}
-	return 0;
-}
-
-
-/* Free a file and its name.  */
-static int
-jffs_free_file(struct jffs_file *f)
-{
-	D3(printk("jffs_free_file: f #%u, \"%s\"\n",
-		  f->ino, (f->name ? f->name : "")));
-
-	if (f->name) {
-		kfree(f->name);
-		DJM(no_name--);
-	}
-	kfree(f);
-	no_jffs_file--;
-	return 0;
-}
-
-static long
-jffs_get_file_count(void)
-{
-	return no_jffs_file;
-}
-
-/* See if a file is deleted. If so, mark that file's nodes as obsolete.  */
-int
-jffs_possibly_delete_file(struct jffs_file *f)
-{
-	struct jffs_node *n;
-
-	D3(printk("jffs_possibly_delete_file(): ino: %u\n",
-		  f->ino));
-
-	ASSERT(if (!f) {
-		printk(KERN_ERR "jffs_possibly_delete_file(): f == NULL\n");
-		return -1;
-	});
-
-	if (f->deleted) {
-		/* First try to remove all older versions.  Commence with
-		   the oldest node.  */
-		for (n = f->version_head; n; n = n->version_next) {
-			if (!n->fm) {
-				continue;
-			}
-			if (jffs_fmfree(f->c->fmc, n->fm, n) < 0) {
-				break;
-			}
-		}
-		/* Unlink the file from the filesystem.  */
-		if (!f->c->building_fs) {
-			jffs_unlink_file_from_tree(f);
-		}
-		jffs_unlink_file_from_hash(f);
-		jffs_free_node_list(f);
-		jffs_free_file(f);
-	}
-	return 0;
-}
-
-
-/* Used in conjunction with jffs_foreach_file() to count the number
-   of files in the file system.  */
-int
-jffs_file_count(struct jffs_file *f)
-{
-	return 1;
-}
-
-
-/* Build up a file's range list from scratch by going through the
-   version list.  */
-static int
-jffs_build_file(struct jffs_file *f)
-{
-	struct jffs_node *n;
-
-	D3(printk("jffs_build_file(): ino: %u, name: \"%s\"\n",
-		  f->ino, (f->name ? f->name : "")));
-
-	for (n = f->version_head; n; n = n->version_next) {
-		jffs_update_file(f, n);
-	}
-	return 0;
-}
-
-
-/* Remove an amount of data from a file. If this amount of data is
-   zero, that could mean that a node should be split in two parts.
-   We remove or change the appropriate nodes in the lists.
-
-   Starting offset of area to be removed is node->data_offset,
-   and the length of the area is in node->removed_size.   */
-static int
-jffs_delete_data(struct jffs_file *f, struct jffs_node *node)
-{
-	struct jffs_node *n;
-	__u32 offset = node->data_offset;
-	__u32 remove_size = node->removed_size;
-
-	D3(printk("jffs_delete_data(): offset = %u, remove_size = %u\n",
-		  offset, remove_size));
-
-	if (remove_size == 0
-	    && f->range_tail
-	    && f->range_tail->data_offset + f->range_tail->data_size
-	       == offset) {
-		/* A simple append; nothing to remove or no node to split.  */
-		return 0;
-	}
-
-	/* Find the node where we should begin the removal.  */
-	for (n = f->range_head; n; n = n->range_next) {
-		if (n->data_offset + n->data_size > offset) {
-			break;
-		}
-	}
-	if (!n) {
-		/* If there's no data in the file there's no data to
-		   remove either.  */
-		return 0;
-	}
-
-	if (n->data_offset > offset) {
-		/* XXX: Not implemented yet.  */
-		printk(KERN_WARNING "JFFS: An unexpected situation "
-		       "occurred in jffs_delete_data.\n");
-	}
-	else if (n->data_offset < offset) {
-		/* See if the node has to be split into two parts.  */
-		if (n->data_offset + n->data_size > offset + remove_size) {
-			/* Do the split.  */
-			struct jffs_node *new_node;
-			D3(printk("jffs_delete_data(): Split node with "
-				  "version number %u.\n", n->version));
-
-			if (!(new_node = jffs_alloc_node())) {
-				D(printk("jffs_delete_data(): -ENOMEM\n"));
-				return -ENOMEM;
-			}
-			DJM(no_jffs_node++);
-
-			new_node->ino = n->ino;
-			new_node->version = n->version;
-			new_node->data_offset = offset;
-			new_node->data_size = n->data_size - (remove_size + (offset - n->data_offset));
-			new_node->fm_offset = n->fm_offset + (remove_size + (offset - n->data_offset));
-			new_node->name_size = n->name_size;
-			new_node->fm = n->fm;
-			new_node->version_prev = n;
-			new_node->version_next = n->version_next;
-			if (new_node->version_next) {
-				new_node->version_next->version_prev
-				= new_node;
-			}
-			else {
-				f->version_tail = new_node;
-			}
-			n->version_next = new_node;
-			new_node->range_prev = n;
-			new_node->range_next = n->range_next;
-			if (new_node->range_next) {
-				new_node->range_next->range_prev = new_node;
-			}
-			else {
-				f->range_tail = new_node;
-			}
-			/* A very interesting can of worms.  */
-			n->range_next = new_node;
-			n->data_size = offset - n->data_offset;
-			if (new_node->fm)
-				jffs_add_node(new_node);
-			else {
-				D1(printk(KERN_WARNING "jffs_delete_data(): Splitting an empty node (file hold).\n!"));
-				D1(printk(KERN_WARNING "FIXME: Did dwmw2 do the right thing here?\n"));
-			}
-			n = new_node->range_next;
-			remove_size = 0;
-		}
-		else {
-			/* No.  No need to split the node.  Just remove
-			   the end of the node.  */
-			int r = min(n->data_offset + n->data_size
-					 - offset, remove_size);
-			n->data_size -= r;
-			remove_size -= r;
-			n = n->range_next;
-		}
-	}
-
-	/* Remove as many nodes as necessary.  */
-	while (n && remove_size) {
-		if (n->data_size <= remove_size) {
-			struct jffs_node *p = n;
-			remove_size -= n->data_size;
-			n = n->range_next;
-			D3(printk("jffs_delete_data(): Removing node: "
-				  "ino: %u, version: %u%s\n",
-				  p->ino, p->version,
-				  (p->fm ? "" : " (virtual)")));
-			if (p->fm) {
-				jffs_fmfree(f->c->fmc, p->fm, p);
-			}
-			jffs_unlink_node_from_range_list(f, p);
-			jffs_unlink_node_from_version_list(f, p);
-			jffs_free_node(p);
-			DJM(no_jffs_node--);
-		}
-		else {
-			n->data_size -= remove_size;
-			n->fm_offset += remove_size;
-			n->data_offset -= (node->removed_size - remove_size);
-			n = n->range_next;
-			break;
-		}
-	}
-
-	/* Adjust the following nodes' information about offsets etc.  */
-	while (n && node->removed_size) {
-		n->data_offset -= node->removed_size;
-		n = n->range_next;
-	}
-
-	if (node->removed_size > (f->size - node->data_offset)) {
-		/* It's possible that the removed_size is in fact
-		 * greater than the amount of data we actually thought
-		 * were present in the first place - some of the nodes 
-		 * which this node originally obsoleted may already have
-		 * been deleted from the flash by subsequent garbage 
-		 * collection.
-		 *
-		 * If this is the case, don't let f->size go negative.
-		 * Bad things would happen :)
-		 */
-		f->size = node->data_offset;
-	} else {
-		f->size -= node->removed_size;
-	}
-	D3(printk("jffs_delete_data(): f->size = %d\n", f->size));
-	return 0;
-} /* jffs_delete_data()  */
-
-
-/* Insert some data into a file.  Prior to the call to this function,
-   jffs_delete_data should be called.  */
-static int
-jffs_insert_data(struct jffs_file *f, struct jffs_node *node)
-{
-	D3(printk("jffs_insert_data(): node->data_offset = %u, "
-		  "node->data_size = %u, f->size = %u\n",
-		  node->data_offset, node->data_size, f->size));
-
-	/* Find the position where we should insert data.  */
-	retry:
-	if (node->data_offset == f->size) {
-		/* A simple append.  This is the most common operation.  */
-		node->range_next = NULL;
-		node->range_prev = f->range_tail;
-		if (node->range_prev) {
-			node->range_prev->range_next = node;
-		}
-		f->range_tail = node;
-		f->size += node->data_size;
-		if (!f->range_head) {
-			f->range_head = node;
-		}
-	}
-	else if (node->data_offset < f->size) {
-		/* Trying to insert data into the middle of the file.  This
-		   means no problem because jffs_delete_data() has already
-		   prepared the range list for us.  */
-		struct jffs_node *n;
-
-		/* Find the correct place for the insertion and then insert
-		   the node.  */
-		for (n = f->range_head; n; n = n->range_next) {
-			D2(printk("Cool stuff's happening!\n"));
-
-			if (n->data_offset == node->data_offset) {
-				node->range_prev = n->range_prev;
-				if (node->range_prev) {
-					node->range_prev->range_next = node;
-				}
-				else {
-					f->range_head = node;
-				}
-				node->range_next = n;
-				n->range_prev = node;
-				break;
-			}
-			ASSERT(else if (n->data_offset + n->data_size >
-					node->data_offset) {
-				printk(KERN_ERR "jffs_insert_data(): "
-				       "Couldn't find a place to insert "
-				       "the data!\n");
-				return -1;
-			});
-		}
-
-		/* Adjust later nodes' offsets etc.  */
-		n = node->range_next;
-		while (n) {
-			n->data_offset += node->data_size;
-			n = n->range_next;
-		}
-		f->size += node->data_size;
-	}
-	else if (node->data_offset > f->size) {
-		/* Okay.  This is tricky.  This means that we want to insert
-		   data at a place that is beyond the limits of the file as
-		   it is constructed right now.  This is actually a common
-		   event that for instance could occur during the mounting
-		   of the file system if a large file have been truncated,
-		   rewritten and then only partially garbage collected.  */
-
-		struct jffs_node *n;
-
-		/* We need a place holder for the data that is missing in
-		   front of this insertion.  This "virtual node" will not
-		   be associated with any space on the flash device.  */
-		struct jffs_node *virtual_node;
-		if (!(virtual_node = jffs_alloc_node())) {
-			return -ENOMEM;
-		}
-
-		D(printk("jffs_insert_data: Inserting a virtual node.\n"));
-		D(printk("  node->data_offset = %u\n", node->data_offset));
-		D(printk("  f->size = %u\n", f->size));
-
-		virtual_node->ino = node->ino;
-		virtual_node->version = node->version;
-		virtual_node->removed_size = 0;
-		virtual_node->fm_offset = 0;
-		virtual_node->name_size = 0;
-		virtual_node->fm = NULL; /* This is a virtual data holder.  */
-		virtual_node->version_prev = NULL;
-		virtual_node->version_next = NULL;
-		virtual_node->range_next = NULL;
-
-		/* Are there any data at all in the file yet?  */
-		if (f->range_head) {
-			virtual_node->data_offset
-			= f->range_tail->data_offset
-			  + f->range_tail->data_size;
-			virtual_node->data_size
-			= node->data_offset - virtual_node->data_offset;
-			virtual_node->range_prev = f->range_tail;
-			f->range_tail->range_next = virtual_node;
-		}
-		else {
-			virtual_node->data_offset = 0;
-			virtual_node->data_size = node->data_offset;
-			virtual_node->range_prev = NULL;
-			f->range_head = virtual_node;
-		}
-
-		f->range_tail = virtual_node;
-		f->size += virtual_node->data_size;
-
-		/* Insert this virtual node in the version list as well.  */
-		for (n = f->version_head; n ; n = n->version_next) {
-			if (n->version == virtual_node->version) {
-				virtual_node->version_prev = n->version_prev;
-				n->version_prev = virtual_node;
-				if (virtual_node->version_prev) {
-					virtual_node->version_prev
-					->version_next = virtual_node;
-				}
-				else {
-					f->version_head = virtual_node;
-				}
-				virtual_node->version_next = n;
-				break;
-			}
-		}
-
-		D(jffs_print_node(virtual_node));
-
-		/* Make a new try to insert the node.  */
-		goto retry;
-	}
-
-	D3(printk("jffs_insert_data(): f->size = %d\n", f->size));
-	return 0;
-}
-
-
-/* A new node (with data) has been added to the file and now the range
-   list has to be modified.  */
-static int
-jffs_update_file(struct jffs_file *f, struct jffs_node *node)
-{
-	int err;
-
-	D3(printk("jffs_update_file(): ino: %u, version: %u\n",
-		  f->ino, node->version));
-
-	if (node->data_size == 0) {
-		if (node->removed_size == 0) {
-			/* data_offset == X  */
-			/* data_size == 0  */
-			/* remove_size == 0  */
-		}
-		else {
-			/* data_offset == X  */
-			/* data_size == 0  */
-			/* remove_size != 0  */
-			if ((err = jffs_delete_data(f, node)) < 0) {
-				return err;
-			}
-		}
-	}
-	else {
-		/* data_offset == X  */
-		/* data_size != 0  */
-		/* remove_size == Y  */
-		if ((err = jffs_delete_data(f, node)) < 0) {
-			return err;
-		}
-		if ((err = jffs_insert_data(f, node)) < 0) {
-			return err;
-		}
-	}
-	return 0;
-}
-
-/* Print the contents of a file.  */
-#if 0
-int
-jffs_print_file(struct jffs_file *f)
-{
-	D(int i);
-	D(printk("jffs_file: 0x%p\n", f));
-	D(printk("{\n"));
-	D(printk("        0x%08x, /* ino  */\n", f->ino));
-	D(printk("        0x%08x, /* pino  */\n", f->pino));
-	D(printk("        0x%08x, /* mode  */\n", f->mode));
-	D(printk("        0x%04x,     /* uid  */\n", f->uid));
-	D(printk("        0x%04x,     /* gid  */\n", f->gid));
-	D(printk("        0x%08x, /* atime  */\n", f->atime));
-	D(printk("        0x%08x, /* mtime  */\n", f->mtime));
-	D(printk("        0x%08x, /* ctime  */\n", f->ctime));
-	D(printk("        0x%02x,       /* nsize  */\n", f->nsize));
-	D(printk("        0x%02x,       /* nlink  */\n", f->nlink));
-	D(printk("        0x%02x,       /* deleted  */\n", f->deleted));
-	D(printk("        \"%s\", ", (f->name ? f->name : "")));
-	D(for (i = strlen(f->name ? f->name : ""); i < 8; ++i) {
-		printk(" ");
-	});
-	D(printk("/* name  */\n"));
-	D(printk("        0x%08x, /* size  */\n", f->size));
-	D(printk("        0x%08x, /* highest_version  */\n",
-		 f->highest_version));
-	D(printk("        0x%p, /* c  */\n", f->c));
-	D(printk("        0x%p, /* parent  */\n", f->parent));
-	D(printk("        0x%p, /* children  */\n", f->children));
-	D(printk("        0x%p, /* sibling_prev  */\n", f->sibling_prev));
-	D(printk("        0x%p, /* sibling_next  */\n", f->sibling_next));
-	D(printk("        0x%p, /* hash_prev  */\n", f->hash.prev));
-	D(printk("        0x%p, /* hash_next  */\n", f->hash.next));
-	D(printk("        0x%p, /* range_head  */\n", f->range_head));
-	D(printk("        0x%p, /* range_tail  */\n", f->range_tail));
-	D(printk("        0x%p, /* version_head  */\n", f->version_head));
-	D(printk("        0x%p, /* version_tail  */\n", f->version_tail));
-	D(printk("}\n"));
-	return 0;
-}
-#endif  /*  0  */
-
-void
-jffs_print_hash_table(struct jffs_control *c)
-{
-	int i;
-
-	printk("JFFS: Dumping the file system's hash table...\n");
-	for (i = 0; i < c->hash_len; i++) {
-		struct jffs_file *f;
-		list_for_each_entry(f, &c->hash[i], hash) {
-			printk("*** c->hash[%u]: \"%s\" "
-			       "(ino: %u, pino: %u)\n",
-			       i, (f->name ? f->name : ""),
-			       f->ino, f->pino);
-		}
-	}
-}
-
-
-void
-jffs_print_tree(struct jffs_file *first_file, int indent)
-{
-	struct jffs_file *f;
-	char *space;
-	int dir;
-
-	if (!first_file) {
-		return;
-	}
-
-	if (!(space = kmalloc(indent + 1, GFP_KERNEL))) {
-		printk("jffs_print_tree(): Out of memory!\n");
-		return;
-	}
-
-	memset(space, ' ', indent);
-	space[indent] = '\0';
-
-	for (f = first_file; f; f = f->sibling_next) {
-		dir = S_ISDIR(f->mode);
-		printk("%s%s%s (ino: %u, highest_version: %u, size: %u)\n",
-		       space, (f->name ? f->name : ""), (dir ? "/" : ""),
-		       f->ino, f->highest_version, f->size);
-		if (dir) {
-			jffs_print_tree(f->children, indent + 2);
-		}
-	}
-
-	kfree(space);
-}
-
-
-#if defined(JFFS_MEMORY_DEBUG) && JFFS_MEMORY_DEBUG
-void
-jffs_print_memory_allocation_statistics(void)
-{
-	static long printout;
-	printk("________ Memory printout #%ld ________\n", ++printout);
-	printk("no_jffs_file = %ld\n", no_jffs_file);
-	printk("no_jffs_node = %ld\n", no_jffs_node);
-	printk("no_jffs_control = %ld\n", no_jffs_control);
-	printk("no_jffs_raw_inode = %ld\n", no_jffs_raw_inode);
-	printk("no_jffs_node_ref = %ld\n", no_jffs_node_ref);
-	printk("no_jffs_fm = %ld\n", no_jffs_fm);
-	printk("no_jffs_fmcontrol = %ld\n", no_jffs_fmcontrol);
-	printk("no_hash = %ld\n", no_hash);
-	printk("no_name = %ld\n", no_name);
-	printk("\n");
-}
-#endif
-
-
-/* Rewrite `size' bytes, and begin at `node'.  */
-static int
-jffs_rewrite_data(struct jffs_file *f, struct jffs_node *node, __u32 size)
-{
-	struct jffs_control *c = f->c;
-	struct jffs_fmcontrol *fmc = c->fmc;
-	struct jffs_raw_inode raw_inode;
-	struct jffs_node *new_node;
-	struct jffs_fm *fm;
-	__u32 pos;
-	__u32 pos_dchksum;
-	__u32 total_name_size;
-	__u32 total_data_size;
-	__u32 total_size;
-	int err;
-
-	D1(printk("***jffs_rewrite_data(): node: %u, name: \"%s\", size: %u\n",
-		  f->ino, (f->name ? f->name : "(null)"), size));
-
-	/* Create and initialize the new node.  */
-	if (!(new_node = jffs_alloc_node())) {
-		D(printk("jffs_rewrite_data(): "
-			 "Failed to allocate node.\n"));
-		return -ENOMEM;
-	}
-	DJM(no_jffs_node++);
-	new_node->data_offset = node->data_offset;
-	new_node->removed_size = size;
-	total_name_size = JFFS_PAD(f->nsize);
-	total_data_size = JFFS_PAD(size);
-	total_size = sizeof(struct jffs_raw_inode)
-		     + total_name_size + total_data_size;
-	new_node->fm_offset = sizeof(struct jffs_raw_inode)
-			      + total_name_size;
-
-retry:
-	jffs_fm_write_lock(fmc);
-	err = 0;
-
-	if ((err = jffs_fmalloc(fmc, total_size, new_node, &fm)) < 0) {
-		DJM(no_jffs_node--);
-		jffs_fm_write_unlock(fmc);
-		D(printk("jffs_rewrite_data(): Failed to allocate fm.\n"));
-		jffs_free_node(new_node);
-		return err;
-	}
-	else if (!fm->nodes) {
-		/* The jffs_fm struct that we got is not big enough.  */
-		/* This should never happen, because we deal with this case
-		   in jffs_garbage_collect_next().*/
-		printk(KERN_WARNING "jffs_rewrite_data(): Allocated node is too small (%d bytes of %d)\n", fm->size, total_size);
-		if ((err = jffs_write_dummy_node(c, fm)) < 0) {
-			D(printk("jffs_rewrite_data(): "
-				 "jffs_write_dummy_node() Failed!\n"));
-		} else {
-			err = -ENOSPC;
-		}
-		DJM(no_jffs_fm--);
-		jffs_fm_write_unlock(fmc);
-		kfree(fm);
-		
-		return err;
-	}
-	new_node->fm = fm;
-
-	/* Initialize the raw inode.  */
-	raw_inode.magic = JFFS_MAGIC_BITMASK;
-	raw_inode.ino = f->ino;
-	raw_inode.pino = f->pino;
-	raw_inode.version = f->highest_version + 1;
-	raw_inode.mode = f->mode;
-	raw_inode.uid = f->uid;
-	raw_inode.gid = f->gid;
-	raw_inode.atime = f->atime;
-	raw_inode.mtime = f->mtime;
-	raw_inode.ctime = f->ctime;
-	raw_inode.offset = node->data_offset;
-	raw_inode.dsize = size;
-	raw_inode.rsize = size;
-	raw_inode.nsize = f->nsize;
-	raw_inode.nlink = f->nlink;
-	raw_inode.spare = 0;
-	raw_inode.rename = 0;
-	raw_inode.deleted = f->deleted;
-	raw_inode.accurate = 0xff;
-	raw_inode.dchksum = 0;
-	raw_inode.nchksum = 0;
-
-	pos = new_node->fm->offset;
-	pos_dchksum = pos +JFFS_RAW_INODE_DCHKSUM_OFFSET;
-
-	D3(printk("jffs_rewrite_data(): Writing this raw inode "
-		  "to pos 0x%ul.\n", pos));
-	D3(jffs_print_raw_inode(&raw_inode));
-
-	if ((err = flash_safe_write(fmc->mtd, pos,
-				    (u_char *) &raw_inode,
-				    sizeof(struct jffs_raw_inode)
-				    - sizeof(__u32)
-				    - sizeof(__u16) - sizeof(__u16))) < 0) {
-		jffs_fmfree_partly(fmc, fm,
-				   total_name_size + total_data_size);
-		jffs_fm_write_unlock(fmc);
-		printk(KERN_ERR "JFFS: jffs_rewrite_data: Write error during "
-			"rewrite. (raw inode)\n");
-		printk(KERN_ERR "JFFS: jffs_rewrite_data: Now retrying "
-			"rewrite. (raw inode)\n");
-		goto retry;
-	}
-	pos += sizeof(struct jffs_raw_inode);
-
-	/* Write the name to the flash memory.  */
-	if (f->nsize) {
-		D3(printk("jffs_rewrite_data(): Writing name \"%s\" to "
-			  "pos 0x%ul.\n", f->name, (unsigned int) pos));
-		if ((err = flash_safe_write(fmc->mtd, pos,
-					    (u_char *)f->name,
-					    f->nsize)) < 0) {
-			jffs_fmfree_partly(fmc, fm, total_data_size);
-			jffs_fm_write_unlock(fmc);
-			printk(KERN_ERR "JFFS: jffs_rewrite_data: Write "
-				"error during rewrite. (name)\n");
-			printk(KERN_ERR "JFFS: jffs_rewrite_data: Now retrying "
-				"rewrite. (name)\n");
-			goto retry;
-		}
-		pos += total_name_size;
-		raw_inode.nchksum = jffs_checksum(f->name, f->nsize);
-	}
-
-	/* Write the data.  */
-	if (size) {
-		int r;
-		unsigned char *page;
-		__u32 offset = node->data_offset;
-
-		if (!(page = (unsigned char *)__get_free_page(GFP_KERNEL))) {
-			jffs_fmfree_partly(fmc, fm, 0);
-			return -1;
-		}
-
-		while (size) {
-			__u32 s = min(size, (__u32)PAGE_SIZE);
-			if ((r = jffs_read_data(f, (char *)page,
-						offset, s)) < s) {
-				free_page((unsigned long)page);
-				jffs_fmfree_partly(fmc, fm, 0);
-				jffs_fm_write_unlock(fmc);
-				printk(KERN_ERR "JFFS: jffs_rewrite_data: "
-					 "jffs_read_data() "
-					 "failed! (r = %d)\n", r);
-				return -1;
-			}
-			if ((err = flash_safe_write(fmc->mtd,
-						    pos, page, r)) < 0) {
-				free_page((unsigned long)page);
-				jffs_fmfree_partly(fmc, fm, 0);
-				jffs_fm_write_unlock(fmc);
-				printk(KERN_ERR "JFFS: jffs_rewrite_data: "
-				       "Write error during rewrite. "
-				       "(data)\n");
-				goto retry;
-			}
-			pos += r;
-			size -= r;
-			offset += r;
-			raw_inode.dchksum += jffs_checksum(page, r);
-		}
-
-	        free_page((unsigned long)page);
-	}
-
-	raw_inode.accurate = 0;
-	raw_inode.chksum = jffs_checksum(&raw_inode,
-					 sizeof(struct jffs_raw_inode)
-					 - sizeof(__u16));
-
-	/* Add the checksum.  */
-	if ((err
-	     = flash_safe_write(fmc->mtd, pos_dchksum,
-				&((u_char *)
-				&raw_inode)[JFFS_RAW_INODE_DCHKSUM_OFFSET],
-				sizeof(__u32) + sizeof(__u16)
-				+ sizeof(__u16))) < 0) {
-		jffs_fmfree_partly(fmc, fm, 0);
-		jffs_fm_write_unlock(fmc);
-		printk(KERN_ERR "JFFS: jffs_rewrite_data: Write error during "
-		       "rewrite. (checksum)\n");
-		goto retry;
-	}
-
-	/* Now make the file system aware of the newly written node.  */
-	jffs_insert_node(c, f, &raw_inode, f->name, new_node);
-	jffs_fm_write_unlock(fmc);
-
-	D3(printk("jffs_rewrite_data(): Leaving...\n"));
-	return 0;
-} /* jffs_rewrite_data()  */
-
-
-/* jffs_garbage_collect_next implements one step in the garbage collect
-   process and is often called multiple times at each occasion of a
-   garbage collect.  */
-
-static int
-jffs_garbage_collect_next(struct jffs_control *c)
-{
-	struct jffs_fmcontrol *fmc = c->fmc;
-	struct jffs_node *node;
-	struct jffs_file *f;
-	int err = 0;
-	__u32 size;
-	__u32 data_size;
-	__u32 total_name_size;
-	__u32 extra_available;
-	__u32 space_needed;
-	__u32 free_chunk_size1 = jffs_free_size1(fmc);
-	D2(__u32 free_chunk_size2 = jffs_free_size2(fmc));
-
-	/* Get the oldest node in the flash.  */
-	node = jffs_get_oldest_node(fmc);
-	ASSERT(if (!node) {
-		printk(KERN_ERR "JFFS: jffs_garbage_collect_next: "
-		       "No oldest node found!\n");
-                err = -1;
-                goto jffs_garbage_collect_next_end;
-		
-
-	});
-
-	/* Find its corresponding file too.  */
-	f = jffs_find_file(c, node->ino);
-
-	if (!f) {
-	  printk (KERN_ERR "JFFS: jffs_garbage_collect_next: "
-                  "No file to garbage collect! "
-		  "(ino = 0x%08x)\n", node->ino);
-          /* FIXME: Free the offending node and recover. */
-          err = -1;
-          goto jffs_garbage_collect_next_end;
-	}
-
-	/* We always write out the name. Theoretically, we don't need
-	   to, but for now it's easier - because otherwise we'd have
-	   to keep track of how many times the current name exists on
-	   the flash and make sure it never reaches zero.
-
-	   The current approach means that would be possible to cause
-	   the GC to end up eating its tail by writing lots of nodes
-	   with no name for it to garbage-collect. Hence the change in
-	   inode.c to write names with _every_ node.
-
-	   It sucks, but it _should_ work.
-	*/
-	total_name_size = JFFS_PAD(f->nsize);
-
-	D1(printk("jffs_garbage_collect_next(): \"%s\", "
-		  "ino: %u, version: %u, location 0x%x, dsize %u\n",
-		  (f->name ? f->name : ""), node->ino, node->version, 
-		  node->fm->offset, node->data_size));
-
-	/* Compute how many data it's possible to rewrite at the moment.  */
-	data_size = f->size - node->data_offset;
-
-	/* And from that, the total size of the chunk we want to write */
-	size = sizeof(struct jffs_raw_inode) + total_name_size
-	       + data_size + JFFS_GET_PAD_BYTES(data_size);
-
-	/* If that's more than max_chunk_size, reduce it accordingly */
-	if (size > fmc->max_chunk_size) {
-		size = fmc->max_chunk_size;
-		data_size = size - sizeof(struct jffs_raw_inode)
-			    - total_name_size;
-	}
-
-	/* If we're asking to take up more space than free_chunk_size1
-	   but we _could_ fit in it, shrink accordingly.
-	*/
-	if (size > free_chunk_size1) {
-
-		if (free_chunk_size1 <
-		    (sizeof(struct jffs_raw_inode) + total_name_size + BLOCK_SIZE)){
-			/* The space left is too small to be of any
-			   use really.  */
-			struct jffs_fm *dirty_fm
-			= jffs_fmalloced(fmc,
-					 fmc->tail->offset + fmc->tail->size,
-					 free_chunk_size1, NULL);
-			if (!dirty_fm) {
-				printk(KERN_ERR "JFFS: "
-				       "jffs_garbage_collect_next: "
-				       "Failed to allocate `dirty' "
-				       "flash memory!\n");
-				err = -1;
-                                goto jffs_garbage_collect_next_end;
-			}
-			D1(printk("Dirtying end of flash - too small\n"));
-			jffs_write_dummy_node(c, dirty_fm);
-                        err = 0;
-			goto jffs_garbage_collect_next_end;
-		}
-		D1(printk("Reducing size of new node from %d to %d to avoid "
-			  " exceeding free_chunk_size1\n",
-			  size, free_chunk_size1));
-
-		size = free_chunk_size1;
-		data_size = size - sizeof(struct jffs_raw_inode)
-			    - total_name_size;
-	}
-
-
-	/* Calculate the amount of space needed to hold the nodes
-	   which are remaining in the tail */
-	space_needed = fmc->min_free_size - (node->fm->offset % fmc->sector_size);
-
-	/* From that, calculate how much 'extra' space we can use to
-	   increase the size of the node we're writing from the size
-	   of the node we're obsoleting
-	*/
-	if (space_needed > fmc->free_size) {
-		/* If we've gone below min_free_size for some reason,
-		   don't fuck up. This is why we have 
-		   min_free_size > sector_size. Whinge about it though,
-		   just so I can convince myself my maths is right.
-		*/
-		D1(printk(KERN_WARNING "jffs_garbage_collect_next(): "
-			  "space_needed %d exceeded free_size %d\n",
-			  space_needed, fmc->free_size));
-		extra_available = 0;
-	} else {
-		extra_available = fmc->free_size - space_needed;
-	}
-
-	/* Check that we don't use up any more 'extra' space than
-	   what's available */
-	if (size > JFFS_PAD(node->data_size) + total_name_size + 
-	    sizeof(struct jffs_raw_inode) + extra_available) {
-		D1(printk("Reducing size of new node from %d to %ld to avoid "
-		       "catching our tail\n", size, 
-			  (long) (JFFS_PAD(node->data_size) + JFFS_PAD(node->name_size) + 
-			  sizeof(struct jffs_raw_inode) + extra_available)));
-		D1(printk("space_needed = %d, extra_available = %d\n", 
-			  space_needed, extra_available));
-
-		size = JFFS_PAD(node->data_size) + total_name_size + 
-		  sizeof(struct jffs_raw_inode) + extra_available;
-		data_size = size - sizeof(struct jffs_raw_inode)
-			- total_name_size;
-	};
-
-	D2(printk("  total_name_size: %u\n", total_name_size));
-	D2(printk("  data_size: %u\n", data_size));
-	D2(printk("  size: %u\n", size));
-	D2(printk("  f->nsize: %u\n", f->nsize));
-	D2(printk("  f->size: %u\n", f->size));
-	D2(printk("  node->data_offset: %u\n", node->data_offset));
-	D2(printk("  free_chunk_size1: %u\n", free_chunk_size1));
-	D2(printk("  free_chunk_size2: %u\n", free_chunk_size2));
-	D2(printk("  node->fm->offset: 0x%08x\n", node->fm->offset));
-
-	if ((err = jffs_rewrite_data(f, node, data_size))) {
-		printk(KERN_WARNING "jffs_rewrite_data() failed: %d\n", err);
-		return err;
-	}
-	  
-jffs_garbage_collect_next_end:
-	D3(printk("jffs_garbage_collect_next: Leaving...\n"));
-	return err;
-} /* jffs_garbage_collect_next */
-
-
-/* If an obsolete node is partly going to be erased due to garbage
-   collection, the part that isn't going to be erased must be filled
-   with zeroes so that the scan of the flash will work smoothly next
-   time.  (The data in the file could for instance be a JFFS image
-   which could cause enormous confusion during a scan of the flash
-   device if we didn't do this.)
-     There are two phases in this procedure: First, the clearing of
-   the name and data parts of the node. Second, possibly also clearing
-   a part of the raw inode as well.  If the box is power cycled during
-   the first phase, only the checksum of this node-to-be-cleared-at-
-   the-end will be wrong.  If the box is power cycled during, or after,
-   the clearing of the raw inode, the information like the length of
-   the name and data parts are zeroed.  The next time the box is
-   powered up, the scanning algorithm manages this faulty data too
-   because:
-
-   - The checksum is invalid and thus the raw inode must be discarded
-     in any case.
-   - If the lengths of the data part or the name part are zeroed, the
-     scanning just continues after the raw inode.  But after the inode
-     the scanning procedure just finds zeroes which is the same as
-     dirt.
-
-   So, in the end, this could never fail. :-)  Even if it does fail,
-   the scanning algorithm should manage that too.  */
-
-static int
-jffs_clear_end_of_node(struct jffs_control *c, __u32 erase_size)
-{
-	struct jffs_fm *fm;
-	struct jffs_fmcontrol *fmc = c->fmc;
-	__u32 zero_offset;
-	__u32 zero_size;
-	__u32 zero_offset_data;
-	__u32 zero_size_data;
-	__u32 cutting_raw_inode = 0;
-
-	if (!(fm = jffs_cut_node(fmc, erase_size))) {
-		D3(printk("jffs_clear_end_of_node(): fm == NULL\n"));
-		return 0;
-	}
-
-	/* Where and how much shall we clear?  */
-	zero_offset = fmc->head->offset + erase_size;
-	zero_size = fm->offset + fm->size - zero_offset;
-
-	/* Do we have to clear the raw_inode explicitly?  */
-	if (fm->size - zero_size < sizeof(struct jffs_raw_inode)) {
-		cutting_raw_inode = sizeof(struct jffs_raw_inode)
-				    - (fm->size - zero_size);
-	}
-
-	/* First, clear the name and data fields.  */
-	zero_offset_data = zero_offset + cutting_raw_inode;
-	zero_size_data = zero_size - cutting_raw_inode;
-	flash_safe_acquire(fmc->mtd);
-	flash_memset(fmc->mtd, zero_offset_data, 0, zero_size_data);
-	flash_safe_release(fmc->mtd);
-
-	/* Should we clear a part of the raw inode?  */
-	if (cutting_raw_inode) {
-		/* I guess it is ok to clear the raw inode in this order.  */
-		flash_safe_acquire(fmc->mtd);
-		flash_memset(fmc->mtd, zero_offset, 0,
-			     cutting_raw_inode);
-		flash_safe_release(fmc->mtd);
-	}
-
-	return 0;
-} /* jffs_clear_end_of_node()  */
-
-/* Try to erase as much as possible of the dirt in the flash memory.  */
-static long
-jffs_try_to_erase(struct jffs_control *c)
-{
-	struct jffs_fmcontrol *fmc = c->fmc;
-	long erase_size;
-	int err;
-	__u32 offset;
-
-	D3(printk("jffs_try_to_erase()\n"));
-
-	erase_size = jffs_erasable_size(fmc);
-
-	D2(printk("jffs_try_to_erase(): erase_size = %ld\n", erase_size));
-
-	if (erase_size == 0) {
-		return 0;
-	}
-	else if (erase_size < 0) {
-		printk(KERN_ERR "JFFS: jffs_try_to_erase: "
-		       "jffs_erasable_size returned %ld.\n", erase_size);
-		return erase_size;
-	}
-
-	if ((err = jffs_clear_end_of_node(c, erase_size)) < 0) {
-		printk(KERN_ERR "JFFS: jffs_try_to_erase: "
-		       "Clearing of node failed.\n");
-		return err;
-	}
-
-	offset = fmc->head->offset;
-
-	/* Now, let's try to do the erase.  */
-	if ((err = flash_erase_region(fmc->mtd,
-				      offset, erase_size)) < 0) {
-		printk(KERN_ERR "JFFS: Erase of flash failed. "
-		       "offset = %u, erase_size = %ld\n",
-		       offset, erase_size);
-		/* XXX: Here we should allocate this area as dirty
-		   with jffs_fmalloced or something similar.  Now
-		   we just report the error.  */
-		return err;
-	}
-
-#if 0
-	/* Check if the erased sectors really got erased.  */
-	{
-		__u32 pos;
-		__u32 end;
-
-		pos = (__u32)flash_get_direct_pointer(to_kdev_t(c->sb->s_dev), offset);
-		end = pos + erase_size;
-
-		D2(printk("JFFS: Checking erased sector(s)...\n"));
-
-		flash_safe_acquire(fmc->mtd);
-
-		for (; pos < end; pos += 4) {
-			if (*(__u32 *)pos != JFFS_EMPTY_BITMASK) {
-				printk("JFFS: Erase failed! pos = 0x%lx\n",
-				       (long)pos);
-				jffs_hexdump(fmc->mtd, pos,
-					     jffs_min(256, end - pos));
-				err = -1;
-				break;
-			}
-		}
-
-		flash_safe_release(fmc->mtd);
-
-		if (!err) {
-			D2(printk("JFFS: Erase succeeded.\n"));
-		}
-		else {
-			/* XXX: Here we should allocate the memory
-			   with jffs_fmalloced() in order to prevent
-			   JFFS from using this area accidentally.  */
-			return err;
-		}
-	}
-#endif
-
-	/* Update the flash memory data structures.  */
-	jffs_sync_erase(fmc, erase_size);
-
-	return erase_size;
-}
-
-
-/* There are different criteria that should trigger a garbage collect:
-
-   1. There is too much dirt in the memory.
-   2. The free space is becoming small.
-   3. There are many versions of a node.
-
-   The garbage collect should always be done in a manner that guarantees
-   that future garbage collects cannot be locked.  E.g. Rewritten chunks
-   should not be too large (span more than one sector in the flash memory
-   for exemple).  Of course there is a limit on how intelligent this garbage
-   collection can be.  */
-
-
-static int
-jffs_garbage_collect_now(struct jffs_control *c)
-{
-	struct jffs_fmcontrol *fmc = c->fmc;
-	long erased = 0;
-	int result = 0;
-	D1(int i = 1);
-	D2(printk("***jffs_garbage_collect_now(): fmc->dirty_size = %u, fmc->free_size = 0x%x\n, fcs1=0x%x, fcs2=0x%x",
-		  fmc->dirty_size, fmc->free_size, jffs_free_size1(fmc), jffs_free_size2(fmc)));
-	D2(jffs_print_fmcontrol(fmc));
-
-	//	down(&fmc->gclock);
-
-	/* If it is possible to garbage collect, do so.  */
-	
-	while (erased == 0) {
-		D1(printk("***jffs_garbage_collect_now(): round #%u, "
-			  "fmc->dirty_size = %u\n", i++, fmc->dirty_size));
-		D2(jffs_print_fmcontrol(fmc));
-
-		if ((erased = jffs_try_to_erase(c)) < 0) {
-			printk(KERN_WARNING "JFFS: Error in "
-			       "garbage collector.\n");
-			result = erased;
-			goto gc_end;
-		}
-		if (erased)
-			break;
-		
-		if (fmc->free_size == 0) {
-			/* Argh */
-			printk(KERN_ERR "jffs_garbage_collect_now(): free_size == 0. This is BAD.\n");
-			result = -ENOSPC;
-			break;
-		}
-
-		if (fmc->dirty_size < fmc->sector_size) {
-			/* Actually, we _may_ have been able to free some, 
-			 * if there are many overlapping nodes which aren't
-			 * actually marked dirty because they still have
-			 * some valid data in each.
-			 */
-			result = -ENOSPC;
-			break;
-		}
-
-		/* Let's dare to make a garbage collect.  */
-		if ((result = jffs_garbage_collect_next(c)) < 0) {
-			printk(KERN_ERR "JFFS: Something "
-			       "has gone seriously wrong "
-			       "with a garbage collect.\n");
-			goto gc_end;
-		}
-
-		D1(printk("   jffs_garbage_collect_now(): erased: %ld\n", erased));
-		DJM(jffs_print_memory_allocation_statistics());
-	}
-	
-gc_end:
-	//	up(&fmc->gclock);
-
-	D3(printk("   jffs_garbage_collect_now(): Leaving...\n"));
-	D1(if (erased) {
-		printk("jffs_g_c_now(): erased = %ld\n", erased);
-		jffs_print_fmcontrol(fmc);
-	});
-
-	if (!erased && !result)
-		return -ENOSPC;
-
-	return result;
-} /* jffs_garbage_collect_now() */
-
-
-/* Determine if it is reasonable to start garbage collection.
-   We start a gc pass if either:
-   - The number of free bytes < MIN_FREE_BYTES && at least one
-     block is dirty, OR
-   - The number of dirty bytes > MAX_DIRTY_BYTES
-*/
-static inline int thread_should_wake (struct jffs_control *c)
-{
-	D1(printk (KERN_NOTICE "thread_should_wake(): free=%d, dirty=%d, blocksize=%d.\n",
-		   c->fmc->free_size, c->fmc->dirty_size, c->fmc->sector_size));
-
-	/* If there's not enough dirty space to free a block, there's no point. */
-	if (c->fmc->dirty_size < c->fmc->sector_size) {
-		D2(printk(KERN_NOTICE "thread_should_wake(): Not waking. Insufficient dirty space\n"));
-		return 0;
-	}
-#if 1
-	/* If there is too much RAM used by the various structures, GC */
-	if (jffs_get_node_inuse() > (c->fmc->used_size/c->fmc->max_chunk_size * 5 + jffs_get_file_count() * 2 + 50)) {
-		/* FIXME: Provide proof that this test can be satisfied. We
-		   don't want a filesystem doing endless GC just because this
-		   condition cannot ever be false.
-		*/
-		D2(printk(KERN_NOTICE "thread_should_wake(): Waking due to number of nodes\n"));
-		return 1;
-	}
-#endif
-	/* If there are fewer free bytes than the threshold, GC */
-	if (c->fmc->free_size < c->gc_minfree_threshold) {
-		D2(printk(KERN_NOTICE "thread_should_wake(): Waking due to insufficent free space\n"));
-		return 1;
-	}
-	/* If there are more dirty bytes than the threshold, GC */
-	if (c->fmc->dirty_size > c->gc_maxdirty_threshold) {
-		D2(printk(KERN_NOTICE "thread_should_wake(): Waking due to excessive dirty space\n"));
-		return 1;
-	}	
-	/* FIXME: What about the "There are many versions of a node" condition? */
-
-	return 0;
-}
-
-
-void jffs_garbage_collect_trigger(struct jffs_control *c)
-{
-	/* NOTE: We rely on the fact that we have the BKL here.
-	 * Otherwise, the gc_task could go away between the check
-	 * and the wake_up_process()
-	 */
-	if (c->gc_task && thread_should_wake(c))
-		send_sig(SIGHUP, c->gc_task, 1);
-}
-  
-
-/* Kernel threads  take (void *) as arguments.   Thus we pass
-   the jffs_control data as a (void *) and then cast it. */
-int
-jffs_garbage_collect_thread(void *ptr)
-{
-        struct jffs_control *c = (struct jffs_control *) ptr;
-	struct jffs_fmcontrol *fmc = c->fmc;
-	long erased;
-	int result = 0;
-	D1(int i = 1);
-
-	daemonize("jffs_gcd");
-
-	c->gc_task = current;
-
-	lock_kernel();
-	init_completion(&c->gc_thread_comp); /* barrier */ 
-	spin_lock_irq(&current->sighand->siglock);
-	siginitsetinv (&current->blocked, sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT));
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	D1(printk (KERN_NOTICE "jffs_garbage_collect_thread(): Starting infinite loop.\n"));
-
-	for (;;) {
-
-		/* See if we need to start gc.  If we don't, go to sleep.
-		   
-		   Current implementation is a BAD THING(tm).  If we try 
-		   to unmount the FS, the unmount operation will sleep waiting
-		   for this thread to exit.  We need to arrange to send it a
-		   sig before the umount process sleeps.
-		*/
-
-		if (!thread_should_wake(c))
-			set_current_state (TASK_INTERRUPTIBLE);
-		
-		schedule(); /* Yes, we do this even if we want to go
-				       on immediately - we're a low priority 
-				       background task. */
-
-		/* Put_super will send a SIGKILL and then wait on the sem. 
-		 */
-		while (signal_pending(current)) {
-			siginfo_t info;
-			unsigned long signr = 0;
-
-			if (try_to_freeze())
-				continue;
-
-			spin_lock_irq(&current->sighand->siglock);
-			signr = dequeue_signal(current, &current->blocked, &info);
-			spin_unlock_irq(&current->sighand->siglock);
-
-			switch(signr) {
-			case SIGSTOP:
-				D1(printk("jffs_garbage_collect_thread(): SIGSTOP received.\n"));
-				set_current_state(TASK_STOPPED);
-				schedule();
-				break;
-
-			case SIGKILL:
-				D1(printk("jffs_garbage_collect_thread(): SIGKILL received.\n"));
-				c->gc_task = NULL;
-				complete_and_exit(&c->gc_thread_comp, 0);
-			}
-		}
-
-
-		D1(printk (KERN_NOTICE "jffs_garbage_collect_thread(): collecting.\n"));
-
-		D3(printk (KERN_NOTICE "g_c_thread(): down biglock\n"));
-		mutex_lock(&fmc->biglock);
-		
-		D1(printk("***jffs_garbage_collect_thread(): round #%u, "
-			  "fmc->dirty_size = %u\n", i++, fmc->dirty_size));
-		D2(jffs_print_fmcontrol(fmc));
-
-		if ((erased = jffs_try_to_erase(c)) < 0) {
-			printk(KERN_WARNING "JFFS: Error in "
-			       "garbage collector: %ld.\n", erased);
-		}
-
-		if (erased)
-			goto gc_end;
-
-		if (fmc->free_size == 0) {
-			/* Argh. Might as well commit suicide. */
-			printk(KERN_ERR "jffs_garbage_collect_thread(): free_size == 0. This is BAD.\n");
-			send_sig(SIGQUIT, c->gc_task, 1);
-			// panic()
-			goto gc_end;
-		}
-		
-		/* Let's dare to make a garbage collect.  */
-		if ((result = jffs_garbage_collect_next(c)) < 0) {
-			printk(KERN_ERR "JFFS: Something "
-			       "has gone seriously wrong "
-			       "with a garbage collect: %d\n", result);
-		}
-		
-	gc_end:
-		D3(printk (KERN_NOTICE "g_c_thread(): up biglock\n"));
-		mutex_unlock(&fmc->biglock);
-	} /* for (;;) */
-} /* jffs_garbage_collect_thread() */
diff --git a/fs/jffs/intrep.h b/fs/jffs/intrep.h
deleted file mode 100644
index 5c7abe0..0000000
--- a/fs/jffs/intrep.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * JFFS -- Journaling Flash File System, Linux implementation.
- *
- * Copyright (C) 1999, 2000  Axis Communications AB.
- *
- * Created by Finn Hakansson <finn@axis.com>.
- *
- * This 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.
- *
- * $Id: intrep.h,v 1.14 2001/09/23 23:28:37 dwmw2 Exp $
- *
- */
-
-#ifndef __LINUX_JFFS_INTREP_H__
-#define __LINUX_JFFS_INTREP_H__
-#include "jffs_fm.h"
-struct jffs_node *jffs_alloc_node(void);
-void jffs_free_node(struct jffs_node *n);
-int jffs_get_node_inuse(void);
-
-void jffs_cleanup_control(struct jffs_control *c);
-int jffs_build_fs(struct super_block *sb);
-
-int jffs_insert_node(struct jffs_control *c, struct jffs_file *f,
-		     const struct jffs_raw_inode *raw_inode,
-		     const char *name, struct jffs_node *node);
-struct jffs_file *jffs_find_file(struct jffs_control *c, __u32 ino);
-struct jffs_file *jffs_find_child(struct jffs_file *dir, const char *name, int len);
-
-void jffs_free_node(struct jffs_node *node);
-
-int jffs_foreach_file(struct jffs_control *c, int (*func)(struct jffs_file *));
-int jffs_possibly_delete_file(struct jffs_file *f);
-int jffs_insert_file_into_tree(struct jffs_file *f);
-int jffs_unlink_file_from_tree(struct jffs_file *f);
-int jffs_file_count(struct jffs_file *f);
-
-int jffs_write_node(struct jffs_control *c, struct jffs_node *node,
-		    struct jffs_raw_inode *raw_inode,
-		    const char *name, const unsigned char *buf,
-		    int recoverable, struct jffs_file *f);
-int jffs_read_data(struct jffs_file *f, unsigned char *buf, __u32 read_offset, __u32 size);
-
-/* Garbage collection stuff.  */
-int jffs_garbage_collect_thread(void *c);
-void jffs_garbage_collect_trigger(struct jffs_control *c);
-
-/* For debugging purposes.  */
-#if 0
-int jffs_print_file(struct jffs_file *f);
-#endif  /*  0  */
-void jffs_print_hash_table(struct jffs_control *c);
-void jffs_print_tree(struct jffs_file *first_file, int indent);
-
-#endif /* __LINUX_JFFS_INTREP_H__  */
diff --git a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c
deleted file mode 100644
index 5a95fbd..0000000
--- a/fs/jffs/jffs_fm.c
+++ /dev/null
@@ -1,798 +0,0 @@
-/*
- * JFFS -- Journaling Flash File System, Linux implementation.
- *
- * Copyright (C) 1999, 2000  Axis Communications AB.
- *
- * Created by Finn Hakansson <finn@axis.com>.
- *
- * This 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.
- *
- * $Id: jffs_fm.c,v 1.27 2001/09/20 12:29:47 dwmw2 Exp $
- *
- * Ported to Linux 2.3.x and MTD:
- * Copyright (C) 2000  Alexander Larsson (alex@cendio.se), Cendio Systems AB
- *
- */
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/blkdev.h>
-#include <linux/jffs.h>
-#include "jffs_fm.h"
-#include "intrep.h"
-
-#if defined(JFFS_MARK_OBSOLETE) && JFFS_MARK_OBSOLETE
-static int jffs_mark_obsolete(struct jffs_fmcontrol *fmc, __u32 fm_offset);
-#endif
-
-static struct jffs_fm *jffs_alloc_fm(void);
-static void jffs_free_fm(struct jffs_fm *n);
-
-extern struct kmem_cache     *fm_cache;
-extern struct kmem_cache     *node_cache;
-
-#if CONFIG_JFFS_FS_VERBOSE > 0
-void
-jffs_print_fmcontrol(struct jffs_fmcontrol *fmc)
-{
-	D(printk("struct jffs_fmcontrol: 0x%p\n", fmc));
-	D(printk("{\n"));
-	D(printk("        %u, /* flash_size  */\n", fmc->flash_size));
-	D(printk("        %u, /* used_size  */\n", fmc->used_size));
-	D(printk("        %u, /* dirty_size  */\n", fmc->dirty_size));
-	D(printk("        %u, /* free_size  */\n", fmc->free_size));
-	D(printk("        %u, /* sector_size  */\n", fmc->sector_size));
-	D(printk("        %u, /* min_free_size  */\n", fmc->min_free_size));
-	D(printk("        %u, /* max_chunk_size  */\n", fmc->max_chunk_size));
-	D(printk("        0x%p, /* mtd  */\n", fmc->mtd));
-	D(printk("        0x%p, /* head  */    "
-		 "(head->offset = 0x%08x)\n",
-		 fmc->head, (fmc->head ? fmc->head->offset : 0)));
-	D(printk("        0x%p, /* tail  */    "
-		 "(tail->offset + tail->size = 0x%08x)\n",
-		 fmc->tail,
-		 (fmc->tail ? fmc->tail->offset + fmc->tail->size : 0)));
-	D(printk("        0x%p, /* head_extra  */\n", fmc->head_extra));
-	D(printk("        0x%p, /* tail_extra  */\n", fmc->tail_extra));
-	D(printk("}\n"));
-}
-#endif  /*  CONFIG_JFFS_FS_VERBOSE > 0  */
-
-#if CONFIG_JFFS_FS_VERBOSE > 2
-static void
-jffs_print_fm(struct jffs_fm *fm)
-{
-	D(printk("struct jffs_fm: 0x%p\n", fm));
-	D(printk("{\n"));
-	D(printk("       0x%08x, /* offset  */\n", fm->offset));
-	D(printk("       %u, /* size  */\n", fm->size));
-	D(printk("       0x%p, /* prev  */\n", fm->prev));
-	D(printk("       0x%p, /* next  */\n", fm->next));
-	D(printk("       0x%p, /* nodes  */\n", fm->nodes));
-	D(printk("}\n"));
-}
-#endif  /*  CONFIG_JFFS_FS_VERBOSE > 2  */
-
-#if 0
-void
-jffs_print_node_ref(struct jffs_node_ref *ref)
-{
-	D(printk("struct jffs_node_ref: 0x%p\n", ref));
-	D(printk("{\n"));
-	D(printk("       0x%p, /* node  */\n", ref->node));
-	D(printk("       0x%p, /* next  */\n", ref->next));
-	D(printk("}\n"));
-}
-#endif  /*  0  */
-
-/* This function creates a new shiny flash memory control structure.  */
-struct jffs_fmcontrol *
-jffs_build_begin(struct jffs_control *c, int unit)
-{
-	struct jffs_fmcontrol *fmc;
-	struct mtd_info *mtd;
-	
-	D3(printk("jffs_build_begin()\n"));
-	fmc = kmalloc(sizeof(*fmc), GFP_KERNEL);
-	if (!fmc) {
-		D(printk("jffs_build_begin(): Allocation of "
-			 "struct jffs_fmcontrol failed!\n"));
-		return (struct jffs_fmcontrol *)0;
-	}
-	DJM(no_jffs_fmcontrol++);
-
-	mtd = get_mtd_device(NULL, unit);
-
-	if (IS_ERR(mtd)) {
-		kfree(fmc);
-		DJM(no_jffs_fmcontrol--);
-		return NULL;
-	}
-	
-	/* Retrieve the size of the flash memory.  */
-	fmc->flash_size = mtd->size;
-	D3(printk("  fmc->flash_size = %d bytes\n", fmc->flash_size));
-
-	fmc->used_size = 0;
-	fmc->dirty_size = 0;
-	fmc->free_size = mtd->size;
-	fmc->sector_size = mtd->erasesize;
-	fmc->max_chunk_size = fmc->sector_size >> 1;
-	/* min_free_size:
-	   1 sector, obviously.
-	   + 1 x max_chunk_size, for when a nodes overlaps the end of a sector
-	   + 1 x max_chunk_size again, which ought to be enough to handle 
-		   the case where a rename causes a name to grow, and GC has
-		   to write out larger nodes than the ones it's obsoleting.
-		   We should fix it so it doesn't have to write the name
-		   _every_ time. Later.
-	   + another 2 sectors because people keep getting GC stuck and
-	           we don't know why. This scares me - I want formal proof
-		   of correctness of whatever number we put here. dwmw2.
-	*/
-	fmc->min_free_size = fmc->sector_size << 2;
-	fmc->mtd = mtd;
-	fmc->c = c;
-	fmc->head = NULL;
-	fmc->tail = NULL;
-	fmc->head_extra = NULL;
-	fmc->tail_extra = NULL;
-	mutex_init(&fmc->biglock);
-	return fmc;
-}
-
-
-/* When the flash memory scan has completed, this function should be called
-   before use of the control structure.  */
-void
-jffs_build_end(struct jffs_fmcontrol *fmc)
-{
-	D3(printk("jffs_build_end()\n"));
-
-	if (!fmc->head) {
-		fmc->head = fmc->head_extra;
-		fmc->tail = fmc->tail_extra;
-	}
-	else if (fmc->head_extra) {
-		fmc->tail_extra->next = fmc->head;
-		fmc->head->prev = fmc->tail_extra;
-		fmc->head = fmc->head_extra;
-	}
-	fmc->head_extra = NULL; /* These two instructions should be omitted.  */
-	fmc->tail_extra = NULL;
-	D3(jffs_print_fmcontrol(fmc));
-}
-
-
-/* Call this function when the file system is unmounted.  This function
-   frees all memory used by this module.  */
-void
-jffs_cleanup_fmcontrol(struct jffs_fmcontrol *fmc)
-{
-	if (fmc) {
-		struct jffs_fm *next = fmc->head;
-		while (next) {
-			struct jffs_fm *cur = next;
-			next = next->next;
-			jffs_free_fm(cur);
-		}
-		put_mtd_device(fmc->mtd);
-		kfree(fmc);
-		DJM(no_jffs_fmcontrol--);
-	}
-}
-
-
-/* This function returns the size of the first chunk of free space on the
-   flash memory.  This function will return something nonzero if the flash
-   memory contains any free space.  */
-__u32
-jffs_free_size1(struct jffs_fmcontrol *fmc)
-{
-	__u32 head;
-	__u32 tail;
-	__u32 end = fmc->flash_size;
-
-	if (!fmc->head) {
-		/* There is nothing on the flash.  */
-		return fmc->flash_size;
-	}
-
-	/* Compute the beginning and ending of the contents of the flash.  */
-	head = fmc->head->offset;
-	tail = fmc->tail->offset + fmc->tail->size;
-	if (tail == end) {
-		tail = 0;
-	}
-	ASSERT(else if (tail > end) {
-		printk(KERN_WARNING "jffs_free_size1(): tail > end\n");
-		tail = 0;
-	});
-
-	if (head <= tail) {
-		return end - tail;
-	}
-	else {
-		return head - tail;
-	}
-}
-
-/* This function will return something nonzero in case there are two free
-   areas on the flash.  Like this:
-
-     +----------------+------------------+----------------+
-     |     FREE 1     |   USED / DIRTY   |     FREE 2     |
-     +----------------+------------------+----------------+
-       fmc->head -----^
-       fmc->tail ------------------------^
-
-   The value returned, will be the size of the first empty area on the
-   flash, in this case marked "FREE 1".  */
-__u32
-jffs_free_size2(struct jffs_fmcontrol *fmc)
-{
-	if (fmc->head) {
-		__u32 head = fmc->head->offset;
-		__u32 tail = fmc->tail->offset + fmc->tail->size;
-		if (tail == fmc->flash_size) {
-			tail = 0;
-		}
-
-		if (tail >= head) {
-			return head;
-		}
-	}
-	return 0;
-}
-
-
-/* Allocate a chunk of flash memory.  If there is enough space on the
-   device, a reference to the associated node is stored in the jffs_fm
-   struct.  */
-int
-jffs_fmalloc(struct jffs_fmcontrol *fmc, __u32 size, struct jffs_node *node,
-	     struct jffs_fm **result)
-{
-	struct jffs_fm *fm;
-	__u32 free_chunk_size1;
-	__u32 free_chunk_size2;
-
-	D2(printk("jffs_fmalloc(): fmc = 0x%p, size = %d, "
-		  "node = 0x%p\n", fmc, size, node));
-
-	*result = NULL;
-
-	if (!(fm = jffs_alloc_fm())) {
-		D(printk("jffs_fmalloc(): kmalloc() failed! (fm)\n"));
-		return -ENOMEM;
-	}
-
-	free_chunk_size1 = jffs_free_size1(fmc);
-	free_chunk_size2 = jffs_free_size2(fmc);
-	if (free_chunk_size1 + free_chunk_size2 != fmc->free_size) {
-		printk(KERN_WARNING "Free size accounting screwed\n");
-		printk(KERN_WARNING "free_chunk_size1 == 0x%x, free_chunk_size2 == 0x%x, fmc->free_size == 0x%x\n", free_chunk_size1, free_chunk_size2, fmc->free_size);
-	}
-
-	D3(printk("jffs_fmalloc(): free_chunk_size1 = %u, "
-		  "free_chunk_size2 = %u\n",
-		  free_chunk_size1, free_chunk_size2));
-
-	if (size <= free_chunk_size1) {
-		if (!(fm->nodes = (struct jffs_node_ref *)
-				  kmalloc(sizeof(struct jffs_node_ref),
-					  GFP_KERNEL))) {
-			D(printk("jffs_fmalloc(): kmalloc() failed! "
-				 "(node_ref)\n"));
-			jffs_free_fm(fm);
-			return -ENOMEM;
-		}
-		DJM(no_jffs_node_ref++);
-		fm->nodes->node = node;
-		fm->nodes->next = NULL;
-		if (fmc->tail) {
-			fm->offset = fmc->tail->offset + fmc->tail->size;
-			if (fm->offset == fmc->flash_size) {
-				fm->offset = 0;
-			}
-			ASSERT(else if (fm->offset > fmc->flash_size) {
-				printk(KERN_WARNING "jffs_fmalloc(): "
-				       "offset > flash_end\n");
-				fm->offset = 0;
-			});
-		}
-		else {
-			/* There don't have to be files in the file
-			   system yet.  */
-			fm->offset = 0;
-		}
-		fm->size = size;
-		fmc->free_size -= size;
-		fmc->used_size += size;
-	}
-	else if (size > free_chunk_size2) {
-		printk(KERN_WARNING "JFFS: Tried to allocate a too "
-		       "large flash memory chunk. (size = %u)\n", size);
-		jffs_free_fm(fm);
-		return -ENOSPC;
-	}
-	else {
-		fm->offset = fmc->tail->offset + fmc->tail->size;
-		fm->size = free_chunk_size1;
-		fm->nodes = NULL;
-		fmc->free_size -= fm->size;
-		fmc->dirty_size += fm->size; /* Changed by simonk. This seemingly fixes a 
-						bug that caused infinite garbage collection.
-						It previously set fmc->dirty_size to size (which is the
-						size of the requested chunk).
-					     */
-	}
-
-	fm->next = NULL;
-	if (!fmc->head) {
-		fm->prev = NULL;
-		fmc->head = fm;
-		fmc->tail = fm;
-	}
-	else {
-		fm->prev = fmc->tail;
-		fmc->tail->next = fm;
-		fmc->tail = fm;
-	}
-
-	D3(jffs_print_fmcontrol(fmc));
-	D3(jffs_print_fm(fm));
-	*result = fm;
-	return 0;
-}
-
-
-/* The on-flash space is not needed anymore by the passed node.  Remove
-   the reference to the node from the node list.  If the data chunk in
-   the flash memory isn't used by any more nodes anymore (fm->nodes == 0),
-   then mark that chunk as dirty.  */
-int
-jffs_fmfree(struct jffs_fmcontrol *fmc, struct jffs_fm *fm, struct jffs_node *node)
-{
-	struct jffs_node_ref *ref;
-	struct jffs_node_ref *prev;
-	ASSERT(int del = 0);
-
-	D2(printk("jffs_fmfree(): node->ino = %u, node->version = %u\n",
-		 node->ino, node->version));
-
-	ASSERT(if (!fmc || !fm || !fm->nodes) {
-		printk(KERN_ERR "jffs_fmfree(): fmc: 0x%p, fm: 0x%p, "
-		       "fm->nodes: 0x%p\n",
-		       fmc, fm, (fm ? fm->nodes : NULL));
-		return -1;
-	});
-
-	/* Find the reference to the node that is going to be removed
-	   and remove it.  */
-	for (ref = fm->nodes, prev = NULL; ref; ref = ref->next) {
-		if (ref->node == node) {
-			if (prev) {
-				prev->next = ref->next;
-			}
-			else {
-				fm->nodes = ref->next;
-			}
-			kfree(ref);
-			DJM(no_jffs_node_ref--);
-			ASSERT(del = 1);
-			break;
-		}
-		prev = ref;
-	}
-
-	/* If the data chunk in the flash memory isn't used anymore
-	   just mark it as obsolete.  */
-	if (!fm->nodes) {
-		/* No node uses this chunk so let's remove it.  */
-		fmc->used_size -= fm->size;
-		fmc->dirty_size += fm->size;
-#if defined(JFFS_MARK_OBSOLETE) && JFFS_MARK_OBSOLETE
-		if (jffs_mark_obsolete(fmc, fm->offset) < 0) {
-			D1(printk("jffs_fmfree(): Failed to mark an on-flash "
-				  "node obsolete!\n"));
-			return -1;
-		}
-#endif
-	}
-
-	ASSERT(if (!del) {
-		printk(KERN_WARNING "***jffs_fmfree(): "
-		       "Didn't delete any node reference!\n");
-	});
-
-	return 0;
-}
-
-
-/* This allocation function is used during the initialization of
-   the file system.  */
-struct jffs_fm *
-jffs_fmalloced(struct jffs_fmcontrol *fmc, __u32 offset, __u32 size,
-	       struct jffs_node *node)
-{
-	struct jffs_fm *fm;
-
-	D3(printk("jffs_fmalloced()\n"));
-
-	if (!(fm = jffs_alloc_fm())) {
-		D(printk("jffs_fmalloced(0x%p, %u, %u, 0x%p): failed!\n",
-			 fmc, offset, size, node));
-		return NULL;
-	}
-	fm->offset = offset;
-	fm->size = size;
-	fm->prev = NULL;
-	fm->next = NULL;
-	fm->nodes = NULL;
-	if (node) {
-		/* `node' exists and it should be associated with the
-		    jffs_fm structure `fm'.  */
-		if (!(fm->nodes = (struct jffs_node_ref *)
-				  kmalloc(sizeof(struct jffs_node_ref),
-					  GFP_KERNEL))) {
-			D(printk("jffs_fmalloced(): !fm->nodes\n"));
-			jffs_free_fm(fm);
-			return NULL;
-		}
-		DJM(no_jffs_node_ref++);
-		fm->nodes->node = node;
-		fm->nodes->next = NULL;
-		fmc->used_size += size;
-		fmc->free_size -= size;
-	}
-	else {
-		/* If there is no node, then this is just a chunk of dirt.  */
-		fmc->dirty_size += size;
-		fmc->free_size -= size;
-	}
-
-	if (fmc->head_extra) {
-		fm->prev = fmc->tail_extra;
-		fmc->tail_extra->next = fm;
-		fmc->tail_extra = fm;
-	}
-	else if (!fmc->head) {
-		fmc->head = fm;
-		fmc->tail = fm;
-	}
-	else if (fmc->tail->offset + fmc->tail->size < offset) {
-		fmc->head_extra = fm;
-		fmc->tail_extra = fm;
-	}
-	else {
-		fm->prev = fmc->tail;
-		fmc->tail->next = fm;
-		fmc->tail = fm;
-	}
-	D3(jffs_print_fmcontrol(fmc));
-	D3(jffs_print_fm(fm));
-	return fm;
-}
-
-
-/* Add a new node to an already existing jffs_fm struct.  */
-int
-jffs_add_node(struct jffs_node *node)
-{
-	struct jffs_node_ref *ref;
-
-	D3(printk("jffs_add_node(): ino = %u\n", node->ino));
-
-	ref = kmalloc(sizeof(*ref), GFP_KERNEL);
-	if (!ref)
-		return -ENOMEM;
-
-	DJM(no_jffs_node_ref++);
-	ref->node = node;
-	ref->next = node->fm->nodes;
-	node->fm->nodes = ref;
-	return 0;
-}
-
-
-/* Free a part of some allocated space.  */
-void
-jffs_fmfree_partly(struct jffs_fmcontrol *fmc, struct jffs_fm *fm, __u32 size)
-{
-	D1(printk("***jffs_fmfree_partly(): fm = 0x%p, fm->nodes = 0x%p, "
-		  "fm->nodes->node->ino = %u, size = %u\n",
-		  fm, (fm ? fm->nodes : 0),
-		  (!fm ? 0 : (!fm->nodes ? 0 : fm->nodes->node->ino)), size));
-
-	if (fm->nodes) {
-		kfree(fm->nodes);
-		DJM(no_jffs_node_ref--);
-		fm->nodes = NULL;
-	}
-	fmc->used_size -= fm->size;
-	if (fm == fmc->tail) {
-		fm->size -= size;
-		fmc->free_size += size;
-	}
-	fmc->dirty_size += fm->size;
-}
-
-
-/* Find the jffs_fm struct that contains the end of the data chunk that
-   begins at the logical beginning of the flash memory and spans `size'
-   bytes.  If we want to erase a sector of the flash memory, we use this
-   function to find where the sector limit cuts a chunk of data.  */
-struct jffs_fm *
-jffs_cut_node(struct jffs_fmcontrol *fmc, __u32 size)
-{
-	struct jffs_fm *fm;
-	__u32 pos = 0;
-
-	if (size == 0) {
-		return NULL;
-	}
-
-	ASSERT(if (!fmc) {
-		printk(KERN_ERR "jffs_cut_node(): fmc == NULL\n");
-		return NULL;
-	});
-
-	fm = fmc->head;
-
-	while (fm) {
-		pos += fm->size;
-		if (pos < size) {
-			fm = fm->next;
-		}
-		else if (pos > size) {
-			break;
-		}
-		else {
-			fm = NULL;
-			break;
-		}
-	}
-
-	return fm;
-}
-
-
-/* Move the head of the fmc structures and delete the obsolete parts.  */
-void
-jffs_sync_erase(struct jffs_fmcontrol *fmc, int erased_size)
-{
-	struct jffs_fm *fm;
-	struct jffs_fm *del;
-
-	ASSERT(if (!fmc) {
-		printk(KERN_ERR "jffs_sync_erase(): fmc == NULL\n");
-		return;
-	});
-
-	fmc->dirty_size -= erased_size;
-	fmc->free_size += erased_size;
-
-	for (fm = fmc->head; fm && (erased_size > 0);) {
-		if (erased_size >= fm->size) {
-			erased_size -= fm->size;
-			del = fm;
-			fm = fm->next;
-			fm->prev = NULL;
-			fmc->head = fm;
-			jffs_free_fm(del);
-		}
-		else {
-			fm->size -= erased_size;
-			fm->offset += erased_size;
-			break;
-		}
-	}
-}
-
-
-/* Return the oldest used node in the flash memory.  */
-struct jffs_node *
-jffs_get_oldest_node(struct jffs_fmcontrol *fmc)
-{
-	struct jffs_fm *fm;
-	struct jffs_node_ref *nref;
-	struct jffs_node *node = NULL;
-
-	ASSERT(if (!fmc) {
-		printk(KERN_ERR "jffs_get_oldest_node(): fmc == NULL\n");
-		return NULL;
-	});
-
-	for (fm = fmc->head; fm && !fm->nodes; fm = fm->next);
-
-	if (!fm) {
-		return NULL;
-	}
-
-	/* The oldest node is the last one in the reference list.  This list
-	   shouldn't be too long; just one or perhaps two elements.  */
-	for (nref = fm->nodes; nref; nref = nref->next) {
-		node = nref->node;
-	}
-
-	D2(printk("jffs_get_oldest_node(): ino = %u, version = %u\n",
-		  (node ? node->ino : 0), (node ? node->version : 0)));
-
-	return node;
-}
-
-
-#if defined(JFFS_MARK_OBSOLETE) && JFFS_MARK_OBSOLETE
-
-/* Mark an on-flash node as obsolete.
-
-   Note that this is just an optimization that isn't necessary for the
-   filesystem to work.  */
-
-static int
-jffs_mark_obsolete(struct jffs_fmcontrol *fmc, __u32 fm_offset)
-{
-	/* The `accurate_pos' holds the position of the accurate byte
-	   in the jffs_raw_inode structure that we are going to mark
-	   as obsolete.  */
-	__u32 accurate_pos = fm_offset + JFFS_RAW_INODE_ACCURATE_OFFSET;
-	unsigned char zero = 0x00;
-	size_t len;
-
-	D3(printk("jffs_mark_obsolete(): accurate_pos = %u\n", accurate_pos));
-	ASSERT(if (!fmc) {
-		printk(KERN_ERR "jffs_mark_obsolete(): fmc == NULL\n");
-		return -1;
-	});
-
-	/* Write 0x00 to the raw inode's accurate member.  Don't care
-	   about the return value.  */
-	MTD_WRITE(fmc->mtd, accurate_pos, 1, &len, &zero);
-	return 0;
-}
-
-#endif /* JFFS_MARK_OBSOLETE  */
-
-/* check if it's possible to erase the wanted range, and if not, return
- * the range that IS erasable, or a negative error code.
- */
-static long
-jffs_flash_erasable_size(struct mtd_info *mtd, __u32 offset, __u32 size)
-{
-         u_long ssize;
-
-	/* assume that sector size for a partition is constant even
-	 * if it spans more than one chip (you usually put the same
-	 * type of chips in a system)
-	 */
-
-        ssize = mtd->erasesize;
-
-	if (offset % ssize) {
-		printk(KERN_WARNING "jffs_flash_erasable_size() given non-aligned offset %x (erasesize %lx)\n", offset, ssize);
-		/* The offset is not sector size aligned.  */
-		return -1;
-	}
-	else if (offset > mtd->size) {
-		printk(KERN_WARNING "jffs_flash_erasable_size given offset off the end of device (%x > %x)\n", offset, mtd->size);
-		return -2;
-	}
-	else if (offset + size > mtd->size) {
-		printk(KERN_WARNING "jffs_flash_erasable_size() given length which runs off the end of device (ofs %x + len %x = %x, > %x)\n", offset,size, offset+size, mtd->size);
-		return -3;
-	}
-
-	return (size / ssize) * ssize;
-}
-
-
-/* How much dirty flash memory is possible to erase at the moment?  */
-long
-jffs_erasable_size(struct jffs_fmcontrol *fmc)
-{
-	struct jffs_fm *fm;
-	__u32 size = 0;
-	long ret;
-
-	ASSERT(if (!fmc) {
-		printk(KERN_ERR "jffs_erasable_size(): fmc = NULL\n");
-		return -1;
-	});
-
-	if (!fmc->head) {
-		/* The flash memory is totally empty. No nodes. No dirt.
-		   Just return.  */
-		return 0;
-	}
-
-	/* Calculate how much space that is dirty.  */
-	for (fm = fmc->head; fm && !fm->nodes; fm = fm->next) {
-		if (size && fm->offset == 0) {
-			/* We have reached the beginning of the flash.  */
-			break;
-		}
-		size += fm->size;
-	}
-
-	/* Someone's signature contained this:
-	   There's a fine line between fishing and just standing on
-	   the shore like an idiot...  */
-	ret = jffs_flash_erasable_size(fmc->mtd, fmc->head->offset, size);
-
-	ASSERT(if (ret < 0) {
-		printk("jffs_erasable_size: flash_erasable_size() "
-		       "returned something less than zero (%ld).\n", ret);
-		printk("jffs_erasable_size: offset = 0x%08x\n",
-		       fmc->head->offset);
-	});
-
-	/* If there is dirt on the flash (which is the reason to why
-	   this function was called in the first place) but no space is
-	   possible to erase right now, the initial part of the list of
-	   jffs_fm structs, that hold place for dirty space, could perhaps
-	   be shortened.  The list's initial "dirty" elements are merged
-	   into just one large dirty jffs_fm struct.  This operation must
-	   only be performed if nothing is possible to erase.  Otherwise,
-	   jffs_clear_end_of_node() won't work as expected.  */
-	if (ret == 0) {
-		struct jffs_fm *head = fmc->head;
-		struct jffs_fm *del;
-		/* While there are two dirty nodes beside each other.*/
-		while (head->nodes == 0
-		       && head->next
-		       && head->next->nodes == 0) {
-			del = head->next;
-			head->size += del->size;
-			head->next = del->next;
-			if (del->next) {
-				del->next->prev = head;
-			}
-			jffs_free_fm(del);
-		}
-	}
-
-	return (ret >= 0 ? ret : 0);
-}
-
-static struct jffs_fm *jffs_alloc_fm(void)
-{
-	struct jffs_fm *fm;
-
-	fm = kmem_cache_alloc(fm_cache,GFP_KERNEL);
-	DJM(if (fm) no_jffs_fm++;);
-	
-	return fm;
-}
-
-static void jffs_free_fm(struct jffs_fm *n)
-{
-	kmem_cache_free(fm_cache,n);
-	DJM(no_jffs_fm--);
-}
-
-
-
-struct jffs_node *jffs_alloc_node(void)
-{
-	struct jffs_node *n;
-
-	n = (struct jffs_node *)kmem_cache_alloc(node_cache,GFP_KERNEL);
-	if(n != NULL)
-		no_jffs_node++;
-	return n;
-}
-
-void jffs_free_node(struct jffs_node *n)
-{
-	kmem_cache_free(node_cache,n);
-	no_jffs_node--;
-}
-
-
-int jffs_get_node_inuse(void)
-{
-	return no_jffs_node;
-}
diff --git a/fs/jffs/jffs_fm.h b/fs/jffs/jffs_fm.h
deleted file mode 100644
index 9ee6ad2..0000000
--- a/fs/jffs/jffs_fm.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * JFFS -- Journaling Flash File System, Linux implementation.
- *
- * Copyright (C) 1999, 2000  Axis Communications AB.
- *
- * Created by Finn Hakansson <finn@axis.com>.
- *
- * This 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.
- *
- * $Id: jffs_fm.h,v 1.13 2001/01/11 12:03:25 dwmw2 Exp $
- *
- * Ported to Linux 2.3.x and MTD:
- * Copyright (C) 2000  Alexander Larsson (alex@cendio.se), Cendio Systems AB
- *
- */
-
-#ifndef __LINUX_JFFS_FM_H__
-#define __LINUX_JFFS_FM_H__
-
-#include <linux/types.h>
-#include <linux/jffs.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mutex.h>
-
-/* The alignment between two nodes in the flash memory.  */
-#define JFFS_ALIGN_SIZE 4
-
-/* Mark the on-flash space as obsolete when appropriate.  */
-#define JFFS_MARK_OBSOLETE 0
-
-#ifndef CONFIG_JFFS_FS_VERBOSE
-#define CONFIG_JFFS_FS_VERBOSE 1
-#endif
-
-#if CONFIG_JFFS_FS_VERBOSE > 0
-#define D(x) x
-#define D1(x) D(x)
-#else
-#define D(x)
-#define D1(x)
-#endif
-
-#if CONFIG_JFFS_FS_VERBOSE > 1
-#define D2(x) D(x)
-#else
-#define D2(x)
-#endif
-
-#if CONFIG_JFFS_FS_VERBOSE > 2
-#define D3(x) D(x)
-#else
-#define D3(x)
-#endif
-
-#define ASSERT(x) x
-
-/* How many padding bytes should be inserted between two chunks of data
-   on the flash?  */
-#define JFFS_GET_PAD_BYTES(size) ( (JFFS_ALIGN_SIZE-1) & -(__u32)(size) )
-#define JFFS_PAD(size) ( (size + (JFFS_ALIGN_SIZE-1)) & ~(JFFS_ALIGN_SIZE-1) )
-
-
-
-struct jffs_node_ref
-{
-	struct jffs_node *node;
-	struct jffs_node_ref *next;
-};
-
-
-/* The struct jffs_fm represents a chunk of data in the flash memory.  */
-struct jffs_fm
-{
-	__u32 offset;
-	__u32 size;
-	struct jffs_fm *prev;
-	struct jffs_fm *next;
-	struct jffs_node_ref *nodes; /* USED if != 0.  */
-};
-
-struct jffs_fmcontrol
-{
-	__u32 flash_size;
-	__u32 used_size;
-	__u32 dirty_size;
-	__u32 free_size;
-	__u32 sector_size;
-	__u32 min_free_size;  /* The minimum free space needed to be able
-				 to perform garbage collections.  */
-	__u32 max_chunk_size; /* The maximum size of a chunk of data.  */
-	struct mtd_info *mtd;
-	struct jffs_control *c;
-	struct jffs_fm *head;
-	struct jffs_fm *tail;
-	struct jffs_fm *head_extra;
-	struct jffs_fm *tail_extra;
-	struct mutex biglock;
-};
-
-/* Notice the two members head_extra and tail_extra in the jffs_control
-   structure above. Those are only used during the scanning of the flash
-   memory; while the file system is being built. If the data in the flash
-   memory is organized like
-
-      +----------------+------------------+----------------+
-      |  USED / DIRTY  |       FREE       |  USED / DIRTY  |
-      +----------------+------------------+----------------+
-
-   then the scan is split in two parts. The first scanned part of the
-   flash memory is organized through the members head and tail. The
-   second scanned part is organized with head_extra and tail_extra. When
-   the scan is completed, the two lists are merged together. The jffs_fm
-   struct that head_extra references is the logical beginning of the
-   flash memory so it will be referenced by the head member.  */
-
-
-
-struct jffs_fmcontrol *jffs_build_begin(struct jffs_control *c, int unit);
-void jffs_build_end(struct jffs_fmcontrol *fmc);
-void jffs_cleanup_fmcontrol(struct jffs_fmcontrol *fmc);
-
-int jffs_fmalloc(struct jffs_fmcontrol *fmc, __u32 size,
-		 struct jffs_node *node, struct jffs_fm **result);
-int jffs_fmfree(struct jffs_fmcontrol *fmc, struct jffs_fm *fm,
-		struct jffs_node *node);
-
-__u32 jffs_free_size1(struct jffs_fmcontrol *fmc);
-__u32 jffs_free_size2(struct jffs_fmcontrol *fmc);
-void jffs_sync_erase(struct jffs_fmcontrol *fmc, int erased_size);
-struct jffs_fm *jffs_cut_node(struct jffs_fmcontrol *fmc, __u32 size);
-struct jffs_node *jffs_get_oldest_node(struct jffs_fmcontrol *fmc);
-long jffs_erasable_size(struct jffs_fmcontrol *fmc);
-struct jffs_fm *jffs_fmalloced(struct jffs_fmcontrol *fmc, __u32 offset,
-			       __u32 size, struct jffs_node *node);
-int jffs_add_node(struct jffs_node *node);
-void jffs_fmfree_partly(struct jffs_fmcontrol *fmc, struct jffs_fm *fm,
-			__u32 size);
-
-#if CONFIG_JFFS_FS_VERBOSE > 0
-void jffs_print_fmcontrol(struct jffs_fmcontrol *fmc);
-#endif
-#if 0
-void jffs_print_node_ref(struct jffs_node_ref *ref);
-#endif  /*  0  */
-
-#endif /* __LINUX_JFFS_FM_H__  */
diff --git a/fs/jffs/jffs_proc.c b/fs/jffs/jffs_proc.c
deleted file mode 100644
index 9bdd99a..0000000
--- a/fs/jffs/jffs_proc.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * JFFS -- Journaling Flash File System, Linux implementation.
- *
- * Copyright (C) 2000  Axis Communications AB.
- *
- * Created by Simon Kagstrom <simonk@axis.com>.
- *
- * $Id: jffs_proc.c,v 1.5 2001/06/02 14:34:55 dwmw2 Exp $
- *
- * This 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.
- *
- *  Overview:
- *   This file defines JFFS partition entries in the proc file system.
- *
- *  TODO:
- *   Create some more proc files for different kinds of info, i.e. statistics
- *   about written and read bytes, number of calls to different routines,
- *   reports about failures.
- */
-
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/jffs.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/time.h>
-#include <linux/types.h>
-#include "jffs_fm.h"
-#include "jffs_proc.h"
-
-/*
- * Structure for a JFFS partition in the system
- */
-struct jffs_partition_dir {
-	struct jffs_control *c;
-	struct proc_dir_entry *part_root;
-	struct proc_dir_entry *part_info;
-	struct proc_dir_entry *part_layout;
-	struct jffs_partition_dir *next;
-};
-
-/*
- * Structure for top-level entry in '/proc/fs' directory
- */
-struct proc_dir_entry *jffs_proc_root;
-
-/*
- * Linked list of 'jffs_partition_dirs' to help us track
- * the mounted JFFS partitions in the system
- */
-static struct jffs_partition_dir *jffs_part_dirs;
-
-/*
- * Read functions for entries
- */
-static int jffs_proc_info_read(char *page, char **start, off_t off,
-		int count, int *eof, void *data);
-static int jffs_proc_layout_read (char *page, char **start, off_t off,
-		int count, int *eof, void *data);
-
-
-/*
- * Register a JFFS partition directory (called upon mount)
- */
-int jffs_register_jffs_proc_dir(int mtd, struct jffs_control *c)
-{
-	struct jffs_partition_dir *part_dir;
-	struct proc_dir_entry *part_info = NULL;
-	struct proc_dir_entry *part_layout = NULL;
-	struct proc_dir_entry *part_root = NULL;
-	char name[10];
-
-	sprintf(name, "%d", mtd);
-	/* Allocate structure for local JFFS partition table */
-	part_dir = (struct jffs_partition_dir *)
-		kmalloc(sizeof (struct jffs_partition_dir), GFP_KERNEL);
-	if (!part_dir)
-		goto out;
-
-	/* Create entry for this partition */
-	part_root = proc_mkdir(name, jffs_proc_root);
-	if (!part_root)
-		goto out1;
-
-	/* Create entry for 'info' file */
-	part_info = create_proc_entry ("info", 0, part_root);
-	if (!part_info)
-		goto out2;
-	part_info->read_proc = jffs_proc_info_read;
-	part_info->data = (void *) c;
-
-	/* Create entry for 'layout' file */
-	part_layout = create_proc_entry ("layout", 0, part_root);
-	if (!part_layout)
-		goto out3;
-	part_layout->read_proc = jffs_proc_layout_read;
-	part_layout->data = (void *) c;
-
-	/* Fill in structure for table and insert in the list */
-	part_dir->c = c;
-	part_dir->part_root = part_root;
-	part_dir->part_info = part_info;
-	part_dir->part_layout = part_layout;
-	part_dir->next = jffs_part_dirs;
-	jffs_part_dirs = part_dir;
-
-	/* Return happy */
-	return 0;
-
-out3:
-	remove_proc_entry("info", part_root);
-out2:
-	remove_proc_entry(name, jffs_proc_root);
-out1:
-	kfree(part_dir);
-out:
-	return -ENOMEM;
-}
-
-
-/*
- * Unregister a JFFS partition directory (called at umount)
- */
-int jffs_unregister_jffs_proc_dir(struct jffs_control *c)
-{
-	struct jffs_partition_dir *part_dir = jffs_part_dirs;
-	struct jffs_partition_dir *prev_part_dir = NULL;
-
-	while (part_dir) {
-		if (part_dir->c == c) {
-			/* Remove entries for partition */
-			remove_proc_entry (part_dir->part_info->name,
-				part_dir->part_root);
-			remove_proc_entry (part_dir->part_layout->name,
-				part_dir->part_root);
-			remove_proc_entry (part_dir->part_root->name,
-				jffs_proc_root);
-
-			/* Remove entry from list */
-			if (prev_part_dir)
-				prev_part_dir->next = part_dir->next;
-			else
-				jffs_part_dirs = part_dir->next;
-
-			/*
-			 * Check to see if this is the last one
-			 * and remove the entry from '/proc/fs'
-			 * if it is.
-			 */
-			if (jffs_part_dirs == part_dir->next)
-				remove_proc_entry ("jffs", proc_root_fs);
-
-			/* Free memory for entry */
-			kfree(part_dir);
-
-			/* Return happy */
-			return 0;
-		}
-
-		/* Move to next entry */
-		prev_part_dir = part_dir;
-		part_dir = part_dir->next;
-	}
-
-	/* Return unhappy */
-	return -1;
-}
-
-
-/*
- * Read a JFFS partition's `info' file
- */
-static int jffs_proc_info_read (char *page, char **start, off_t off,
-		int count, int *eof, void *data)
-{
-	struct jffs_control *c = (struct jffs_control *) data;
-	int len = 0;
-
-	/* Get information on the parition */
-	len += sprintf (page,
-		"partition size:     %08lX (%u)\n"
-		"sector size:        %08lX (%u)\n"
-		"used size:          %08lX (%u)\n"
-		"dirty size:         %08lX (%u)\n"
-		"free size:          %08lX (%u)\n\n",
-		(unsigned long) c->fmc->flash_size, c->fmc->flash_size,
-		(unsigned long) c->fmc->sector_size, c->fmc->sector_size,
-		(unsigned long) c->fmc->used_size, c->fmc->used_size,
-		(unsigned long) c->fmc->dirty_size, c->fmc->dirty_size,
-		(unsigned long) (c->fmc->flash_size -
-			(c->fmc->used_size + c->fmc->dirty_size)),
-		c->fmc->flash_size - (c->fmc->used_size + c->fmc->dirty_size));
-
-	/* We're done */
-	*eof = 1;
-
-	/* Return length */
-	return len;
-}
-
-
-/*
- * Read a JFFS partition's `layout' file
- */
-static int jffs_proc_layout_read (char *page, char **start, off_t off,
-		int count, int *eof, void *data)
-{
-	struct jffs_control *c = (struct jffs_control *) data;
-	struct jffs_fm *fm = NULL;
-	struct jffs_fm *last_fm = NULL;
-	int len = 0;
-
-	/* Get the first item in the list */
- 	fm = c->fmc->head;
-
-	/* Print free space */
-	if (fm && fm->offset) {
-		len += sprintf (page, "00000000 %08lX free\n",
-			(unsigned long) fm->offset);
-	}
-
-	/* Loop through all of the flash control structures */
-	while (fm && (len < (off + count))) {
-		if (fm->nodes) {
-			len += sprintf (page + len,
-				"%08lX %08lX ino=%08lX, ver=%08lX\n",
-				(unsigned long) fm->offset,
-				(unsigned long) fm->size,
-				(unsigned long) fm->nodes->node->ino,
-				(unsigned long) fm->nodes->node->version);
-		}
-		else {
-			len += sprintf (page + len,
-				"%08lX %08lX dirty\n",
-				(unsigned long) fm->offset,
-				(unsigned long) fm->size);
-		}
-		last_fm = fm;
-		fm = fm->next;
-	}
-
-	/* Print free space */
-	if ((len < (off + count)) && last_fm
-	    && (last_fm->offset < c->fmc->flash_size)) {
-		len += sprintf (page + len,
-			       "%08lX %08lX free\n",
-			       (unsigned long) last_fm->offset + 
-				last_fm->size,
-			       (unsigned long) (c->fmc->flash_size -
-						    (last_fm->offset + last_fm->size)));
-	}
-
-	/* We're done */
-	*eof = 1;
-
-	/* Return length */
-	return len;
-}
diff --git a/fs/jffs/jffs_proc.h b/fs/jffs/jffs_proc.h
deleted file mode 100644
index 39a1c5d..0000000
--- a/fs/jffs/jffs_proc.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * JFFS -- Journaling Flash File System, Linux implementation.
- *
- * Copyright (C) 2000  Axis Communications AB.
- *
- * Created by Simon Kagstrom <simonk@axis.com>.
- *
- * This 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.
- *
- * $Id: jffs_proc.h,v 1.2 2000/11/15 22:04:12 sjhill Exp $
- */
-
-/* jffs_proc.h defines a structure for inclusion in the proc-file system.  */
-#ifndef __LINUX_JFFS_PROC_H__
-#define __LINUX_JFFS_PROC_H__
-
-#include <linux/proc_fs.h>
-
-/* The proc_dir_entry for jffs (defined in jffs_proc.c).  */
-extern struct proc_dir_entry *jffs_proc_root;
-
-int jffs_register_jffs_proc_dir(int mtd, struct jffs_control *c);
-int jffs_unregister_jffs_proc_dir(struct jffs_control *c);
-
-#endif /* __LINUX_JFFS_PROC_H__ */
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
index 0282696..07119c4 100644
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -348,23 +348,27 @@
 
 	ret = jffs2_sum_init(c);
 	if (ret)
-		return ret;
+		goto out_free;
 
 	if (jffs2_build_filesystem(c)) {
 		dbg_fsbuild("build_fs failed\n");
 		jffs2_free_ino_caches(c);
 		jffs2_free_raw_node_refs(c);
-#ifndef __ECOS
-		if (jffs2_blocks_use_vmalloc(c))
-			vfree(c->blocks);
-		else
-#endif
-			kfree(c->blocks);
-
-		return -EIO;
+		ret = -EIO;
+		goto out_free;
 	}
 
 	jffs2_calc_trigger_levels(c);
 
 	return 0;
+
+ out_free:
+#ifndef __ECOS
+	if (jffs2_blocks_use_vmalloc(c))
+		vfree(c->blocks);
+	else
+#endif
+		kfree(c->blocks);
+
+	return ret;
 }
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h
index b985949..ea88f69 100644
--- a/fs/jffs2/jffs2_fs_sb.h
+++ b/fs/jffs2/jffs2_fs_sb.h
@@ -98,20 +98,14 @@
 	uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */
 
 #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
-	/* Write-behind buffer for NAND flash */
-	unsigned char *wbuf;
-	unsigned char *oobbuf;
+	unsigned char *wbuf; /* Write-behind buffer for NAND flash */
 	uint32_t wbuf_ofs;
 	uint32_t wbuf_len;
 	struct jffs2_inodirty *wbuf_inodes;
-
 	struct rw_semaphore wbuf_sem;	/* Protects the write buffer */
 
-	/* Information about out-of-band area usage... */
-	struct nand_ecclayout *ecclayout;
-	uint32_t badblock_pos;
-	uint32_t fsdata_pos;
-	uint32_t fsdata_len;
+	unsigned char *oobbuf;
+	int oobavail; /* How many bytes are available for JFFS2 in OOB */
 #endif
 
 	struct jffs2_summary *summary;		/* Summary information */
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 3af746e..31c1475 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -450,16 +450,20 @@
 
 #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
 	if (jffs2_cleanmarker_oob(c)) {
-		int ret = jffs2_check_nand_cleanmarker(c, jeb);
+		int ret;
+
+		if (c->mtd->block_isbad(c->mtd, jeb->offset))
+			return BLK_STATE_BADBLOCK;
+
+		ret = jffs2_check_nand_cleanmarker(c, jeb);
 		D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret));
+
 		/* Even if it's not found, we still scan to see
 		   if the block is empty. We use this information
 		   to decide whether to erase it or not. */
 		switch (ret) {
 		case 0:		cleanmarkerfound = 1; break;
 		case 1: 	break;
-		case 2: 	return BLK_STATE_BADBLOCK;
-		case 3:		return BLK_STATE_ALLDIRTY; /* Block has failed to erase min. once */
 		default: 	return ret;
 		}
 	}
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 9c99859..de718e3 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -957,43 +957,48 @@
 	return ret;
 }
 
-#define NR_OOB_SCAN_PAGES	4
+#define NR_OOB_SCAN_PAGES 4
+
+/* For historical reasons we use only 12 bytes for OOB clean marker */
+#define OOB_CM_SIZE 12
+
+static const struct jffs2_unknown_node oob_cleanmarker =
+{
+	.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
+	.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
+	.totlen = cpu_to_je32(8)
+};
 
 /*
- * Check, if the out of band area is empty
+ * Check, if the out of band area is empty. This function knows about the clean
+ * marker and if it is present in OOB, treats the OOB as empty anyway.
  */
 int jffs2_check_oob_empty(struct jffs2_sb_info *c,
 			  struct jffs2_eraseblock *jeb, int mode)
 {
-	int i, page, ret;
-	int oobsize = c->mtd->oobsize;
+	int i, ret;
+	int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
 	struct mtd_oob_ops ops;
 
-	ops.ooblen = NR_OOB_SCAN_PAGES * oobsize;
+	ops.mode = MTD_OOB_AUTO;
+	ops.ooblen = NR_OOB_SCAN_PAGES * c->oobavail;
 	ops.oobbuf = c->oobbuf;
-	ops.ooboffs = 0;
+	ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
 	ops.datbuf = NULL;
-	ops.mode = MTD_OOB_PLACE;
 
 	ret = c->mtd->read_oob(c->mtd, jeb->offset, &ops);
-	if (ret) {
-		D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB "
-			  "failed %d for block at %08x\n", ret, jeb->offset));
+	if (ret || ops.oobretlen != ops.ooblen) {
+		printk(KERN_ERR "cannot read OOB for EB at %08x, requested %zd"
+				" bytes, read %zd bytes, error %d\n",
+				jeb->offset, ops.ooblen, ops.oobretlen, ret);
+		if (!ret)
+			ret = -EIO;
 		return ret;
 	}
 
-	if (ops.oobretlen < ops.ooblen) {
-		D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB "
-			  "returned short read (%zd bytes not %d) for block "
-			  "at %08x\n", ops.oobretlen, ops.ooblen, jeb->offset));
-		return -EIO;
-	}
-
-	/* Special check for first page */
-	for(i = 0; i < oobsize ; i++) {
-		/* Yeah, we know about the cleanmarker. */
-		if (mode && i >= c->fsdata_pos &&
-		    i < c->fsdata_pos + c->fsdata_len)
+	for(i = 0; i < ops.ooblen; i++) {
+		if (mode && i < cmlen)
+			/* Yeah, we know about the cleanmarker */
 			continue;
 
 		if (ops.oobbuf[i] != 0xFF) {
@@ -1003,111 +1008,63 @@
 		}
 	}
 
-	/* we know, we are aligned :) */
-	for (page = oobsize; page < ops.ooblen; page += sizeof(long)) {
-		long dat = *(long *)(&ops.oobbuf[page]);
-		if(dat != -1)
-			return 1;
-	}
 	return 0;
 }
 
 /*
- * Scan for a valid cleanmarker and for bad blocks
+ * Check for a valid cleanmarker.
+ * Returns: 0 if a valid cleanmarker was found
+ *          1 if no cleanmarker was found
+ *          negative error code if an error occurred
  */
-int jffs2_check_nand_cleanmarker (struct jffs2_sb_info *c,
-				  struct jffs2_eraseblock *jeb)
+int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c,
+				 struct jffs2_eraseblock *jeb)
 {
-	struct jffs2_unknown_node n;
 	struct mtd_oob_ops ops;
-	int oobsize = c->mtd->oobsize;
-	unsigned char *p,*b;
-	int i, ret;
-	size_t offset = jeb->offset;
+	int ret, cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
 
-	/* Check first if the block is bad. */
-	if (c->mtd->block_isbad(c->mtd, offset)) {
-		D1 (printk(KERN_WARNING "jffs2_check_nand_cleanmarker()"
-			   ": Bad block at %08x\n", jeb->offset));
-		return 2;
-	}
-
-	ops.ooblen = oobsize;
+	ops.mode = MTD_OOB_AUTO;
+	ops.ooblen = cmlen;
 	ops.oobbuf = c->oobbuf;
-	ops.ooboffs = 0;
+	ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
 	ops.datbuf = NULL;
-	ops.mode = MTD_OOB_PLACE;
 
-	ret = c->mtd->read_oob(c->mtd, offset, &ops);
-	if (ret) {
-		D1 (printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): "
-			   "Read OOB failed %d for block at %08x\n",
-			   ret, jeb->offset));
+	ret = c->mtd->read_oob(c->mtd, jeb->offset, &ops);
+	if (ret || ops.oobretlen != ops.ooblen) {
+		printk(KERN_ERR "cannot read OOB for EB at %08x, requested %zd"
+				" bytes, read %zd bytes, error %d\n",
+				jeb->offset, ops.ooblen, ops.oobretlen, ret);
+		if (!ret)
+			ret = -EIO;
 		return ret;
 	}
 
-	if (ops.oobretlen < ops.ooblen) {
-		D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): "
-			    "Read OOB return short read (%zd bytes not %d) "
-			    "for block at %08x\n", ops.oobretlen, ops.ooblen,
-			    jeb->offset));
-		return -EIO;
-	}
-
-	n.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
-	n.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER);
-	n.totlen = cpu_to_je32 (8);
-	p = (unsigned char *) &n;
-	b = c->oobbuf + c->fsdata_pos;
-
-	for (i = c->fsdata_len; i; i--) {
-		if (*b++ != *p++)
-			ret = 1;
-	}
-
-	D1(if (ret == 1) {
-		printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): "
-		       "Cleanmarker node not detected in block at %08x\n",
-		       offset);
-		printk(KERN_WARNING "OOB at %08zx was ", offset);
-		for (i=0; i < oobsize; i++)
-			printk("%02x ", c->oobbuf[i]);
-		printk("\n");
-	});
-	return ret;
+	return !!memcmp(&oob_cleanmarker, c->oobbuf, cmlen);
 }
 
 int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c,
 				 struct jffs2_eraseblock *jeb)
 {
-	struct jffs2_unknown_node n;
-	int	ret;
+	int ret;
 	struct mtd_oob_ops ops;
+	int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
 
-	n.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-	n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
-	n.totlen = cpu_to_je32(8);
-
-	ops.ooblen = c->fsdata_len;
-	ops.oobbuf = (uint8_t *)&n;
-	ops.ooboffs = c->fsdata_pos;
+	ops.mode = MTD_OOB_AUTO;
+	ops.ooblen = cmlen;
+	ops.oobbuf = (uint8_t *)&oob_cleanmarker;
+	ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
 	ops.datbuf = NULL;
-	ops.mode = MTD_OOB_PLACE;
 
 	ret = c->mtd->write_oob(c->mtd, jeb->offset, &ops);
-
-	if (ret) {
-		D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): "
-			  "Write failed for block at %08x: error %d\n",
-			  jeb->offset, ret));
+	if (ret || ops.oobretlen != ops.ooblen) {
+		printk(KERN_ERR "cannot write OOB for EB at %08x, requested %zd"
+				" bytes, read %zd bytes, error %d\n",
+				jeb->offset, ops.ooblen, ops.oobretlen, ret);
+		if (!ret)
+			ret = -EIO;
 		return ret;
 	}
-	if (ops.oobretlen != ops.ooblen) {
-		D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): "
-			  "Short write for block at %08x: %zd not %d\n",
-			  jeb->offset, ops.oobretlen, ops.ooblen));
-		return -EIO;
-	}
+
 	return 0;
 }
 
@@ -1140,41 +1097,24 @@
 	return 1;
 }
 
-static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c)
+int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
 {
 	struct nand_ecclayout *oinfo = c->mtd->ecclayout;
 
-	/* Do this only, if we have an oob buffer */
 	if (!c->mtd->oobsize)
 		return 0;
 
 	/* Cleanmarker is out-of-band, so inline size zero */
 	c->cleanmarker_size = 0;
 
-	/* Should we use autoplacement ? */
-	if (!oinfo) {
-		D1(printk(KERN_DEBUG "JFFS2 on NAND. No autoplacment info found\n"));
+	if (!oinfo || oinfo->oobavail == 0) {
+		printk(KERN_ERR "inconsistent device description\n");
 		return -EINVAL;
 	}
 
-	D1(printk(KERN_DEBUG "JFFS2 using autoplace on NAND\n"));
-	/* Get the position of the free bytes */
-	if (!oinfo->oobfree[0].length) {
-		printk (KERN_WARNING "jffs2_nand_set_oobinfo(): Eeep."
-			" Autoplacement selected and no empty space in oob\n");
-		return -ENOSPC;
-	}
-	c->fsdata_pos = oinfo->oobfree[0].offset;
-	c->fsdata_len = oinfo->oobfree[0].length;
-	if (c->fsdata_len > 8)
-		c->fsdata_len = 8;
+	D1(printk(KERN_DEBUG "JFFS2 using OOB on NAND\n"));
 
-	return 0;
-}
-
-int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
-{
-	int res;
+	c->oobavail = oinfo->oobavail;
 
 	/* Initialise write buffer */
 	init_rwsem(&c->wbuf_sem);
@@ -1185,22 +1125,13 @@
 	if (!c->wbuf)
 		return -ENOMEM;
 
-	c->oobbuf = kmalloc(NR_OOB_SCAN_PAGES * c->mtd->oobsize, GFP_KERNEL);
-	if (!c->oobbuf)
-		return -ENOMEM;
-
-	res = jffs2_nand_set_oobinfo(c);
-
-#ifdef BREAKME
-	if (!brokenbuf)
-		brokenbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
-	if (!brokenbuf) {
+	c->oobbuf = kmalloc(NR_OOB_SCAN_PAGES * c->oobavail, GFP_KERNEL);
+	if (!c->oobbuf) {
 		kfree(c->wbuf);
 		return -ENOMEM;
 	}
-	memset(brokenbuf, 0xdb, c->wbuf_pagesize);
-#endif
-	return res;
+
+	return 0;
 }
 
 void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c)
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 50cb8da..126b1bf 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -440,7 +440,7 @@
 };
 
 /*
- * Module (and driverfs) parameters.
+ * Module (and sysfs) parameters.
  */
 
 #define param_set_min_max(name, type, which_strtol, min, max)		\
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index edde5dc..b617428 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -287,13 +287,20 @@
 	return 1;
 }
 
-static int nfsaclsvc_release_fhandle(struct svc_rqst *rqstp, __be32 *p,
-		struct nfsd_fhandle *resp)
+static int nfsaclsvc_release_attrstat(struct svc_rqst *rqstp, __be32 *p,
+		struct nfsd_attrstat *resp)
 {
 	fh_put(&resp->fh);
 	return 1;
 }
 
+static int nfsaclsvc_release_access(struct svc_rqst *rqstp, __be32 *p,
+               struct nfsd3_accessres *resp)
+{
+       fh_put(&resp->fh);
+       return 1;
+}
+
 #define nfsaclsvc_decode_voidargs	NULL
 #define nfsaclsvc_encode_voidres	NULL
 #define nfsaclsvc_release_void		NULL
@@ -322,9 +329,9 @@
 static struct svc_procedure		nfsd_acl_procedures2[] = {
   PROC(null,	void,		void,		void,	  RC_NOCACHE, ST),
   PROC(getacl,	getacl,		getacl,		getacl,	  RC_NOCACHE, ST+1+2*(1+ACL)),
-  PROC(setacl,	setacl,		attrstat,	fhandle,  RC_NOCACHE, ST+AT),
-  PROC(getattr, fhandle,	attrstat,	fhandle,  RC_NOCACHE, ST+AT),
-  PROC(access,	access,		access,		fhandle,  RC_NOCACHE, ST+AT+1),
+  PROC(setacl,	setacl,		attrstat,	attrstat, RC_NOCACHE, ST+AT),
+  PROC(getattr, fhandle,	attrstat,	attrstat, RC_NOCACHE, ST+AT),
+  PROC(access,	access,		access,		access,   RC_NOCACHE, ST+AT+1),
 };
 
 struct svc_version	nfsd_acl_version2 = {
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index f7fa52b..28dd757 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -1098,7 +1098,7 @@
 			BUG();
 	}
 
-	/* Assume a directory heirarchy thusly:
+	/* Assume a directory hierarchy thusly:
 	 * a/b/c
 	 * a/d
 	 * a,b,c, and d are all directories.
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index ac32a2e..22d38ff 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -358,8 +358,7 @@
 	p->ios[0] = p->ios[1] = 0;
 	p->sectors[0] = p->sectors[1] = 0;
 	sysfs_remove_link(&p->kobj, "subsystem");
-	if (p->holder_dir)
-		kobject_unregister(p->holder_dir);
+	kobject_unregister(p->holder_dir);
 	kobject_uevent(&p->kobj, KOBJ_REMOVE);
 	kobject_del(&p->kobj);
 	kobject_put(&p->kobj);
@@ -603,10 +602,8 @@
 	disk->stamp = 0;
 
 	kobject_uevent(&disk->kobj, KOBJ_REMOVE);
-	if (disk->holder_dir)
-		kobject_unregister(disk->holder_dir);
-	if (disk->slave_dir)
-		kobject_unregister(disk->slave_dir);
+	kobject_unregister(disk->holder_dir);
+	kobject_unregister(disk->slave_dir);
 	if (disk->driverfs_dev) {
 		char *disk_name = make_block_name(disk);
 		sysfs_remove_link(&disk->kobj, "device");
diff --git a/fs/pipe.c b/fs/pipe.c
index 68090e8..ebafde7 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -16,6 +16,7 @@
 #include <linux/uio.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
+#include <linux/audit.h>
 
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
@@ -985,6 +986,10 @@
 		goto err_fdr;
 	fdw = error;
 
+	error = audit_fd_pair(fdr, fdw);
+	if (error < 0)
+		goto err_fdw;
+
 	fd_install(fdr, fr);
 	fd_install(fdw, fw);
 	fd[0] = fdr;
@@ -992,6 +997,8 @@
 
 	return 0;
 
+ err_fdw:
+	put_unused_fd(fdw);
  err_fdr:
 	put_unused_fd(fdr);
  err_read_pipe:
diff --git a/fs/stack.c b/fs/stack.c
index 8ffb880d..67716f6 100644
--- a/fs/stack.c
+++ b/fs/stack.c
@@ -20,11 +20,6 @@
 void fsstack_copy_attr_all(struct inode *dest, const struct inode *src,
 				int (*get_nlinks)(struct inode *))
 {
-	if (!get_nlinks)
-		dest->i_nlink = src->i_nlink;
-	else
-		dest->i_nlink = (*get_nlinks)(dest);
-
 	dest->i_mode = src->i_mode;
 	dest->i_uid = src->i_uid;
 	dest->i_gid = src->i_gid;
@@ -34,5 +29,14 @@
 	dest->i_ctime = src->i_ctime;
 	dest->i_blkbits = src->i_blkbits;
 	dest->i_flags = src->i_flags;
+
+	/*
+	 * Update the nlinks AFTER updating the above fields, because the
+	 * get_links callback may depend on them.
+	 */
+	if (!get_nlinks)
+		dest->i_nlink = src->i_nlink;
+	else
+		dest->i_nlink = (*get_nlinks)(dest);
 }
 EXPORT_SYMBOL_GPL(fsstack_copy_attr_all);
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index c0e1176..98b0910 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -54,7 +54,7 @@
 /**
  *	add_to_collection - add buffer to a collection
  *	@buffer:	buffer to be added
- *	@node		inode of set to add to
+ *	@node:		inode of set to add to
  */
 
 static inline void
diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h
index ce7c9d6..73967c8 100644
--- a/include/acpi/acinterp.h
+++ b/include/acpi/acinterp.h
@@ -253,7 +253,8 @@
 
 void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread);
 
-void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc);
+void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc,
+			  struct acpi_thread_state *thread);
 
 /*
  * exprep - ACPI AML execution - prep utilities
diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h
index 04e9735..5206d61 100644
--- a/include/acpi/acobject.h
+++ b/include/acpi/acobject.h
@@ -155,7 +155,7 @@
 struct acpi_object_mutex {
 	ACPI_OBJECT_COMMON_HEADER u8 sync_level;	/* 0-15, specified in Mutex() call */
 	u16 acquisition_depth;	/* Allow multiple Acquires, same thread */
-	struct acpi_thread_state *owner_thread;	/* Current owner of the mutex */
+	acpi_thread_id owner_thread_id;	/* Current owner of the mutex */
 	acpi_mutex os_mutex;	/* Actual OS synchronization object */
 	union acpi_operand_object *prev;	/* Link for list of acquired mutexes */
 	union acpi_operand_object *next;	/* Link for list of acquired mutexes */
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index 4dc8a50..f6275b0 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -105,12 +105,6 @@
 
 int acpi_processor_set_thermal_limit(acpi_handle handle, int type);
 
-/* --------------------------------------------------------------------------
-                                    Hot Keys
-   -------------------------------------------------------------------------- */
-
-extern int acpi_specific_hotkey_enabled;
-
 /*--------------------------------------------------------------------------
                                   Dock Station
   -------------------------------------------------------------------------- */
@@ -122,10 +116,34 @@
 	acpi_notify_handler handler, void *context);
 extern void unregister_hotplug_dock_device(acpi_handle handle);
 #else
-#define is_dock_device(h)			(0)
-#define register_dock_notifier(nb) 		(-ENODEV)
-#define unregister_dock_notifier(nb)           	do { } while(0)
-#define register_hotplug_dock_device(h1, h2, c)	(-ENODEV)
-#define unregister_hotplug_dock_device(h)       do { } while(0)
+static inline int is_dock_device(acpi_handle handle)
+{
+	return 0;
+}
+static inline int register_dock_notifier(struct notifier_block *nb)
+{
+	return -ENODEV;
+}
+static inline void unregister_dock_notifier(struct notifier_block *nb)
+{
+}
+static inline int register_hotplug_dock_device(acpi_handle handle,
+				acpi_notify_handler handler, void *context)
+{
+	return -ENODEV;
+}
+static inline void unregister_hotplug_dock_device(acpi_handle handle)
+{
+}
 #endif
+
+/*--------------------------------------------------------------------------
+                                  Suspend/Resume
+  -------------------------------------------------------------------------- */
+#ifdef CONFIG_ACPI_SLEEP
+extern int acpi_sleep_init(void);
+#else
+#define acpi_sleep_init() do {} while (0)
+#endif
+
 #endif /*__ACPI_DRIVERS_H__*/
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index 781394b..2785058 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -240,12 +240,6 @@
 acpi_os_validate_address(u8 space_id,
 			 acpi_physical_address address, acpi_size length);
 
-u8 acpi_os_readable(void *pointer, acpi_size length);
-
-#ifdef ACPI_FUTURE_USAGE
-u8 acpi_os_writable(void *pointer, acpi_size length);
-#endif
-
 u64 acpi_os_get_timer(void);
 
 acpi_status acpi_os_signal(u32 function, void *info);
diff --git a/include/asm-arm/.gitignore b/include/asm-arm/.gitignore
new file mode 100644
index 0000000..e02c15d
--- /dev/null
+++ b/include/asm-arm/.gitignore
@@ -0,0 +1,2 @@
+arch
+mach-types.h
diff --git a/include/asm-arm/arch-at91rm9200/at91_aic.h b/include/asm-arm/arch-at91/at91_aic.h
similarity index 97%
rename from include/asm-arm/arch-at91rm9200/at91_aic.h
rename to include/asm-arm/arch-at91/at91_aic.h
index 267e698..df44c12 100644
--- a/include/asm-arm/arch-at91rm9200/at91_aic.h
+++ b/include/asm-arm/arch-at91/at91_aic.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_aic.h
+ * include/asm-arm/arch-at91/at91_aic.h
  *
  * Copyright (C) 2005 Ivan Kokshaysky
  * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_dbgu.h b/include/asm-arm/arch-at91/at91_dbgu.h
similarity index 76%
rename from include/asm-arm/arch-at91rm9200/at91_dbgu.h
rename to include/asm-arm/arch-at91/at91_dbgu.h
index e4b8b27..b0369e1 100644
--- a/include/asm-arm/arch-at91rm9200/at91_dbgu.h
+++ b/include/asm-arm/arch-at91/at91_dbgu.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_dbgu.h
+ * include/asm-arm/arch-at91/at91_dbgu.h
  *
  * Copyright (C) 2005 Ivan Kokshaysky
  * Copyright (C) SAN People
@@ -35,6 +35,20 @@
 #define		AT91_CIDR_NVPSIZ	(0xf  << 8)		/* Nonvolatile Program Memory Size */
 #define		AT91_CIDR_NVPSIZ2	(0xf  << 12)		/* Second Nonvolatile Program Memory Size */
 #define		AT91_CIDR_SRAMSIZ	(0xf  << 16)		/* Internal SRAM Size */
+#define			AT91_CIDR_SRAMSIZ_1K	(1 << 16)
+#define			AT91_CIDR_SRAMSIZ_2K	(2 << 16)
+#define			AT91_CIDR_SRAMSIZ_112K	(4 << 16)
+#define			AT91_CIDR_SRAMSIZ_4K	(5 << 16)
+#define			AT91_CIDR_SRAMSIZ_80K	(6 << 16)
+#define			AT91_CIDR_SRAMSIZ_160K	(7 << 16)
+#define			AT91_CIDR_SRAMSIZ_8K	(8 << 16)
+#define			AT91_CIDR_SRAMSIZ_16K	(9 << 16)
+#define			AT91_CIDR_SRAMSIZ_32K	(10 << 16)
+#define			AT91_CIDR_SRAMSIZ_64K	(11 << 16)
+#define			AT91_CIDR_SRAMSIZ_128K	(12 << 16)
+#define			AT91_CIDR_SRAMSIZ_256K	(13 << 16)
+#define			AT91_CIDR_SRAMSIZ_96K	(14 << 16)
+#define			AT91_CIDR_SRAMSIZ_512K	(15 << 16)
 #define		AT91_CIDR_ARCH		(0xff << 20)		/* Architecture Identifier */
 #define		AT91_CIDR_NVPTYP	(7    << 28)		/* Nonvolatile Program Memory Type */
 #define		AT91_CIDR_EXT		(1    << 31)		/* Extension Flag */
diff --git a/include/asm-arm/arch-at91rm9200/at91_ecc.h b/include/asm-arm/arch-at91/at91_ecc.h
similarity index 96%
rename from include/asm-arm/arch-at91rm9200/at91_ecc.h
rename to include/asm-arm/arch-at91/at91_ecc.h
index 5c564ed..ff93df5 100644
--- a/include/asm-arm/arch-at91rm9200/at91_ecc.h
+++ b/include/asm-arm/arch-at91/at91_ecc.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_ecc.h
+ * include/asm-arm/arch-at91/at91_ecc.h
  *
  * Error Corrected Code Controller (ECC) - System peripherals regsters.
  * Based on AT91SAM9260 datasheet revision B.
diff --git a/include/asm-arm/arch-at91rm9200/at91_lcdc.h b/include/asm-arm/arch-at91/at91_lcdc.h
similarity index 99%
rename from include/asm-arm/arch-at91rm9200/at91_lcdc.h
rename to include/asm-arm/arch-at91/at91_lcdc.h
index 9cbfcdd..ab040a4 100644
--- a/include/asm-arm/arch-at91rm9200/at91_lcdc.h
+++ b/include/asm-arm/arch-at91/at91_lcdc.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_lcdc.h
+ * include/asm-arm/arch-at91/at91_lcdc.h
  *
  * LCD Controller (LCDC).
  * Based on AT91SAM9261 datasheet revision E.
diff --git a/include/asm-arm/arch-at91rm9200/at91_mci.h b/include/asm-arm/arch-at91/at91_mci.h
similarity index 98%
rename from include/asm-arm/arch-at91rm9200/at91_mci.h
rename to include/asm-arm/arch-at91/at91_mci.h
index 9a552cb..40a9876 100644
--- a/include/asm-arm/arch-at91rm9200/at91_mci.h
+++ b/include/asm-arm/arch-at91/at91_mci.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_mci.h
+ * include/asm-arm/arch-at91/at91_mci.h
  *
  * Copyright (C) 2005 Ivan Kokshaysky
  * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_pio.h b/include/asm-arm/arch-at91/at91_pio.h
similarity index 97%
rename from include/asm-arm/arch-at91rm9200/at91_pio.h
rename to include/asm-arm/arch-at91/at91_pio.h
index 680eaa1..84c3866 100644
--- a/include/asm-arm/arch-at91rm9200/at91_pio.h
+++ b/include/asm-arm/arch-at91/at91_pio.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_pio.h
+ * include/asm-arm/arch-at91/at91_pio.h
  *
  * Copyright (C) 2005 Ivan Kokshaysky
  * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_pit.h b/include/asm-arm/arch-at91/at91_pit.h
similarity index 95%
rename from include/asm-arm/arch-at91rm9200/at91_pit.h
rename to include/asm-arm/arch-at91/at91_pit.h
index 4a30d009..5026325 100644
--- a/include/asm-arm/arch-at91rm9200/at91_pit.h
+++ b/include/asm-arm/arch-at91/at91_pit.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_pit.h
+ * include/asm-arm/arch-at91/at91_pit.h
  *
  * Periodic Interval Timer (PIT) - System peripherals regsters.
  * Based on AT91SAM9261 datasheet revision D.
diff --git a/include/asm-arm/arch-at91rm9200/at91_pmc.h b/include/asm-arm/arch-at91/at91_pmc.h
similarity index 98%
rename from include/asm-arm/arch-at91rm9200/at91_pmc.h
rename to include/asm-arm/arch-at91/at91_pmc.h
index c3b489d..33ff5b6 100644
--- a/include/asm-arm/arch-at91rm9200/at91_pmc.h
+++ b/include/asm-arm/arch-at91/at91_pmc.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_pmc.h
+ * include/asm-arm/arch-at91/at91_pmc.h
  *
  * Copyright (C) 2005 Ivan Kokshaysky
  * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_rstc.h b/include/asm-arm/arch-at91/at91_rstc.h
similarity index 90%
rename from include/asm-arm/arch-at91rm9200/at91_rstc.h
rename to include/asm-arm/arch-at91/at91_rstc.h
index 237d3c4..fb8d161 100644
--- a/include/asm-arm/arch-at91rm9200/at91_rstc.h
+++ b/include/asm-arm/arch-at91/at91_rstc.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_rstc.h
+ * include/asm-arm/arch-at91/at91_rstc.h
  *
  * Reset Controller (RSTC) - System peripherals regsters.
  * Based on AT91SAM9261 datasheet revision D.
@@ -17,7 +17,7 @@
 #define		AT91_RSTC_PROCRST	(1 << 0)		/* Processor Reset */
 #define		AT91_RSTC_PERRST	(1 << 2)		/* Peripheral Reset */
 #define		AT91_RSTC_EXTRST	(1 << 3)		/* External Reset */
-#define		AT91_RSTC_KEY		(0xff << 24)		/* KEY Password */
+#define		AT91_RSTC_KEY		(0xa5 << 24)		/* KEY Password */
 
 #define AT91_RSTC_SR		(AT91_RSTC + 0x04)	/* Reset Controller Status Register */
 #define		AT91_RSTC_URSTS		(1 << 0)		/* User Reset Status */
@@ -34,6 +34,5 @@
 #define		AT91_RSTC_URSTEN	(1 << 0)		/* User Reset Enable */
 #define		AT91_RSTC_URSTIEN	(1 << 4)		/* User Reset Interrupt Enable */
 #define		AT91_RSTC_ERSTL		(0xf << 8)		/* External Reset Length */
-#define		AT91_RSTC_KEY		(0xff << 24)		/* KEY Password */
 
 #endif
diff --git a/include/asm-arm/arch-at91rm9200/at91_rtc.h b/include/asm-arm/arch-at91/at91_rtc.h
similarity index 98%
rename from include/asm-arm/arch-at91rm9200/at91_rtc.h
rename to include/asm-arm/arch-at91/at91_rtc.h
index 095fe08..af9bd28 100644
--- a/include/asm-arm/arch-at91rm9200/at91_rtc.h
+++ b/include/asm-arm/arch-at91/at91_rtc.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_rtc.h
+ * include/asm-arm/arch-at91/at91_rtc.h
  *
  * Copyright (C) 2005 Ivan Kokshaysky
  * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_rtt.h b/include/asm-arm/arch-at91/at91_rtt.h
similarity index 96%
rename from include/asm-arm/arch-at91rm9200/at91_rtt.h
rename to include/asm-arm/arch-at91/at91_rtt.h
index c6751ba..bae1103 100644
--- a/include/asm-arm/arch-at91rm9200/at91_rtt.h
+++ b/include/asm-arm/arch-at91/at91_rtt.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_rtt.h
+ * include/asm-arm/arch-at91/at91_rtt.h
  *
  * Real-time Timer (RTT) - System peripherals regsters.
  * Based on AT91SAM9261 datasheet revision D.
diff --git a/include/asm-arm/arch-at91rm9200/at91_shdwc.h b/include/asm-arm/arch-at91/at91_shdwc.h
similarity index 96%
rename from include/asm-arm/arch-at91rm9200/at91_shdwc.h
rename to include/asm-arm/arch-at91/at91_shdwc.h
index 0439250..795fcc2 100644
--- a/include/asm-arm/arch-at91rm9200/at91_shdwc.h
+++ b/include/asm-arm/arch-at91/at91_shdwc.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_shdwc.h
+ * include/asm-arm/arch-at91/at91_shdwc.h
  *
  * Shutdown Controller (SHDWC) - System peripherals regsters.
  * Based on AT91SAM9261 datasheet revision D.
diff --git a/include/asm-arm/arch-at91rm9200/at91_spi.h b/include/asm-arm/arch-at91/at91_spi.h
similarity index 98%
rename from include/asm-arm/arch-at91rm9200/at91_spi.h
rename to include/asm-arm/arch-at91/at91_spi.h
index bec48ca..f9b9a84 100644
--- a/include/asm-arm/arch-at91rm9200/at91_spi.h
+++ b/include/asm-arm/arch-at91/at91_spi.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_spi.h
+ * include/asm-arm/arch-at91/at91_spi.h
  *
  * Copyright (C) 2005 Ivan Kokshaysky
  * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_ssc.h b/include/asm-arm/arch-at91/at91_ssc.h
similarity index 98%
rename from include/asm-arm/arch-at91rm9200/at91_ssc.h
rename to include/asm-arm/arch-at91/at91_ssc.h
index 694bcaa..0ecc734 100644
--- a/include/asm-arm/arch-at91rm9200/at91_ssc.h
+++ b/include/asm-arm/arch-at91/at91_ssc.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_ssc.h
+ * include/asm-arm/arch-at91/at91_ssc.h
  *
  * Copyright (C) SAN People
  *
diff --git a/include/asm-arm/arch-at91rm9200/at91_st.h b/include/asm-arm/arch-at91/at91_st.h
similarity index 97%
rename from include/asm-arm/arch-at91rm9200/at91_st.h
rename to include/asm-arm/arch-at91/at91_st.h
index 2432ddf..30446e2 100644
--- a/include/asm-arm/arch-at91rm9200/at91_st.h
+++ b/include/asm-arm/arch-at91/at91_st.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_st.h
+ * include/asm-arm/arch-at91/at91_st.h
  *
  * Copyright (C) 2005 Ivan Kokshaysky
  * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_tc.h b/include/asm-arm/arch-at91/at91_tc.h
similarity index 99%
rename from include/asm-arm/arch-at91rm9200/at91_tc.h
rename to include/asm-arm/arch-at91/at91_tc.h
index 8d06eb0..b85d3fa 100644
--- a/include/asm-arm/arch-at91rm9200/at91_tc.h
+++ b/include/asm-arm/arch-at91/at91_tc.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_tc.h
+ * include/asm-arm/arch-at91/at91_tc.h
  *
  * Copyright (C) SAN People
  *
diff --git a/include/asm-arm/arch-at91rm9200/at91_twi.h b/include/asm-arm/arch-at91/at91_twi.h
similarity index 97%
rename from include/asm-arm/arch-at91rm9200/at91_twi.h
rename to include/asm-arm/arch-at91/at91_twi.h
index cda914f..ca9a907 100644
--- a/include/asm-arm/arch-at91rm9200/at91_twi.h
+++ b/include/asm-arm/arch-at91/at91_twi.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_twi.h
+ * include/asm-arm/arch-at91/at91_twi.h
  *
  * Copyright (C) 2005 Ivan Kokshaysky
  * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_wdt.h b/include/asm-arm/arch-at91/at91_wdt.h
similarity index 96%
rename from include/asm-arm/arch-at91rm9200/at91_wdt.h
rename to include/asm-arm/arch-at91/at91_wdt.h
index ac63e77..7251a34 100644
--- a/include/asm-arm/arch-at91rm9200/at91_wdt.h
+++ b/include/asm-arm/arch-at91/at91_wdt.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91_wdt.h
+ * include/asm-arm/arch-at91/at91_wdt.h
  *
  * Watchdog Timer (WDT) - System peripherals regsters.
  * Based on AT91SAM9261 datasheet revision D.
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200.h b/include/asm-arm/arch-at91/at91rm9200.h
similarity index 99%
rename from include/asm-arm/arch-at91rm9200/at91rm9200.h
rename to include/asm-arm/arch-at91/at91rm9200.h
index c569b6a..a12ac8a 100644
--- a/include/asm-arm/arch-at91rm9200/at91rm9200.h
+++ b/include/asm-arm/arch-at91/at91rm9200.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91rm9200.h
+ * include/asm-arm/arch-at91/at91rm9200.h
  *
  * Copyright (C) 2005 Ivan Kokshaysky
  * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_emac.h b/include/asm-arm/arch-at91/at91rm9200_emac.h
similarity index 98%
rename from include/asm-arm/arch-at91rm9200/at91rm9200_emac.h
rename to include/asm-arm/arch-at91/at91rm9200_emac.h
index fbc091e..0c417af 100644
--- a/include/asm-arm/arch-at91rm9200/at91rm9200_emac.h
+++ b/include/asm-arm/arch-at91/at91rm9200_emac.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91rm9200_emac.h
+ * include/asm-arm/arch-at91/at91rm9200_emac.h
  *
  * Copyright (C) 2005 Ivan Kokshaysky
  * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_mc.h b/include/asm-arm/arch-at91/at91rm9200_mc.h
similarity index 99%
rename from include/asm-arm/arch-at91rm9200/at91rm9200_mc.h
rename to include/asm-arm/arch-at91/at91rm9200_mc.h
index 0c0d814..24d0129 100644
--- a/include/asm-arm/arch-at91rm9200/at91rm9200_mc.h
+++ b/include/asm-arm/arch-at91/at91rm9200_mc.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91rm9200_mc.h
+ * include/asm-arm/arch-at91/at91rm9200_mc.h
  *
  * Copyright (C) 2005 Ivan Kokshaysky
  * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91sam9260.h b/include/asm-arm/arch-at91/at91sam9260.h
similarity index 95%
rename from include/asm-arm/arch-at91rm9200/at91sam9260.h
rename to include/asm-arm/arch-at91/at91sam9260.h
index 46f4dd6..2cadebc 100644
--- a/include/asm-arm/arch-at91rm9200/at91sam9260.h
+++ b/include/asm-arm/arch-at91/at91sam9260.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91sam9260.h
+ * include/asm-arm/arch-at91/at91sam9260.h
  *
  * (C) 2006 Andrew Victor
  *
@@ -113,6 +113,10 @@
 
 #define AT91SAM9260_UHP_BASE	0x00500000	/* USB Host controller */
 
+#define AT91SAM9XE_FLASH_BASE	0x00200000	/* Internal FLASH base address */
+#define AT91SAM9XE_SRAM_BASE	0x00300000	/* Internal SRAM base address */
+
+
 #if 0
 /*
  * PIO pin definitions (peripheral A/B multiplexing).
diff --git a/include/asm-arm/arch-at91rm9200/at91sam9260_matrix.h b/include/asm-arm/arch-at91/at91sam9260_matrix.h
similarity index 96%
rename from include/asm-arm/arch-at91rm9200/at91sam9260_matrix.h
rename to include/asm-arm/arch-at91/at91sam9260_matrix.h
index 78f6b49..aacb1e9 100644
--- a/include/asm-arm/arch-at91rm9200/at91sam9260_matrix.h
+++ b/include/asm-arm/arch-at91/at91sam9260_matrix.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91sam9260_matrix.h
+ * include/asm-arm/arch-at91/at91sam9260_matrix.h
  *
  * Memory Controllers (MATRIX, EBI) - System peripherals registers.
  * Based on AT91SAM9260 datasheet revision B.
@@ -18,7 +18,7 @@
 #define AT91_MATRIX_MCFG2	(AT91_MATRIX + 0x08)	/* Master Configuration Register 2 */
 #define AT91_MATRIX_MCFG3	(AT91_MATRIX + 0x0C)	/* Master Configuration Register 3 */
 #define AT91_MATRIX_MCFG4	(AT91_MATRIX + 0x10)	/* Master Configuration Register 4 */
-#define AT91_MATRIX_MCFG5	(AT91_MATRIX + 0x04)	/* Master Configuration Register 5 */
+#define AT91_MATRIX_MCFG5	(AT91_MATRIX + 0x14)	/* Master Configuration Register 5 */
 #define		AT91_MATRIX_ULBT		(7 << 0)	/* Undefined Length Burst Type */
 #define			AT91_MATRIX_ULBT_INFINITE	(0 << 0)
 #define			AT91_MATRIX_ULBT_SINGLE		(1 << 0)
diff --git a/include/asm-arm/arch-at91rm9200/at91sam9261.h b/include/asm-arm/arch-at91/at91sam9261.h
similarity index 99%
rename from include/asm-arm/arch-at91rm9200/at91sam9261.h
rename to include/asm-arm/arch-at91/at91sam9261.h
index 8d39672..01b58ff 100644
--- a/include/asm-arm/arch-at91rm9200/at91sam9261.h
+++ b/include/asm-arm/arch-at91/at91sam9261.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91sam9261.h
+ * include/asm-arm/arch-at91/at91sam9261.h
  *
  * Copyright (C) SAN People
  *
diff --git a/include/asm-arm/arch-at91rm9200/at91sam9261_matrix.h b/include/asm-arm/arch-at91/at91sam9261_matrix.h
similarity index 97%
rename from include/asm-arm/arch-at91rm9200/at91sam9261_matrix.h
rename to include/asm-arm/arch-at91/at91sam9261_matrix.h
index ec88efa..6f07242 100644
--- a/include/asm-arm/arch-at91rm9200/at91sam9261_matrix.h
+++ b/include/asm-arm/arch-at91/at91sam9261_matrix.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91sam9261_matrix.h
+ * include/asm-arm/arch-at91/at91sam9261_matrix.h
  *
  * Memory Controllers (MATRIX, EBI) - System peripherals registers.
  * Based on AT91SAM9261 datasheet revision D.
diff --git a/include/asm-arm/arch-at91/at91sam9263.h b/include/asm-arm/arch-at91/at91sam9263.h
new file mode 100644
index 0000000..f4af68a
--- /dev/null
+++ b/include/asm-arm/arch-at91/at91sam9263.h
@@ -0,0 +1,131 @@
+/*
+ * include/asm-arm/arch-at91/at91sam9263.h
+ *
+ * (C) 2007 Atmel Corporation.
+ *
+ * Common definitions.
+ * Based on AT91SAM9263 datasheet revision B (Preliminary).
+ *
+ * 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.
+ */
+
+#ifndef AT91SAM9263_H
+#define AT91SAM9263_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91_ID_FIQ		0	/* Advanced Interrupt Controller (FIQ) */
+#define AT91_ID_SYS		1	/* System Peripherals */
+#define AT91SAM9263_ID_PIOA	2	/* Parallel IO Controller A */
+#define AT91SAM9263_ID_PIOB	3	/* Parallel IO Controller B */
+#define AT91SAM9263_ID_PIOCDE	4	/* Parallel IO Controller C, D and E */
+#define AT91SAM9263_ID_US0	7	/* USART 0 */
+#define AT91SAM9263_ID_US1	8	/* USART 1 */
+#define AT91SAM9263_ID_US2	9	/* USART 2 */
+#define AT91SAM9263_ID_MCI0	10	/* Multimedia Card Interface 0 */
+#define AT91SAM9263_ID_MCI1	11	/* Multimedia Card Interface 1 */
+#define AT91SAM9263_ID_CAN	12	/* CAN */
+#define AT91SAM9263_ID_TWI	13	/* Two-Wire Interface */
+#define AT91SAM9263_ID_SPI0	14	/* Serial Peripheral Interface 0 */
+#define AT91SAM9263_ID_SPI1	15	/* Serial Peripheral Interface 1 */
+#define AT91SAM9263_ID_SSC0	16	/* Serial Synchronous Controller 0 */
+#define AT91SAM9263_ID_SSC1	17	/* Serial Synchronous Controller 1 */
+#define AT91SAM9263_ID_AC97C	18	/* AC97 Controller */
+#define AT91SAM9263_ID_TCB	19	/* Timer Counter 0, 1 and 2 */
+#define AT91SAM9263_ID_PWMC	20	/* Pulse Width Modulation Controller */
+#define AT91SAM9263_ID_EMAC	21	/* Ethernet */
+#define AT91SAM9263_ID_2DGE	23	/* 2D Graphic Engine */
+#define AT91SAM9263_ID_UDP	24	/* USB Device Port */
+#define AT91SAM9263_ID_ISI	25	/* Image Sensor Interface */
+#define AT91SAM9263_ID_LCDC	26	/* LCD Controller */
+#define AT91SAM9263_ID_DMA	27	/* DMA Controller */
+#define AT91SAM9263_ID_UHP	29	/* USB Host port */
+#define AT91SAM9263_ID_IRQ0	30	/* Advanced Interrupt Controller (IRQ0) */
+#define AT91SAM9263_ID_IRQ1	31	/* Advanced Interrupt Controller (IRQ1) */
+
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define AT91SAM9263_BASE_UDP		0xfff78000
+#define AT91SAM9263_BASE_TCB0		0xfff7c000
+#define AT91SAM9263_BASE_TC0		0xfff7c000
+#define AT91SAM9263_BASE_TC1		0xfff7c040
+#define AT91SAM9263_BASE_TC2		0xfff7c080
+#define AT91SAM9263_BASE_MCI0		0xfff80000
+#define AT91SAM9263_BASE_MCI1		0xfff84000
+#define AT91SAM9263_BASE_TWI		0xfff88000
+#define AT91SAM9263_BASE_US0		0xfff8c000
+#define AT91SAM9263_BASE_US1		0xfff90000
+#define AT91SAM9263_BASE_US2		0xfff94000
+#define AT91SAM9263_BASE_SSC0		0xfff98000
+#define AT91SAM9263_BASE_SSC1		0xfff9c000
+#define AT91SAM9263_BASE_AC97C		0xfffa0000
+#define AT91SAM9263_BASE_SPI0		0xfffa4000
+#define AT91SAM9263_BASE_SPI1		0xfffa8000
+#define AT91SAM9263_BASE_CAN		0xfffac000
+#define AT91SAM9263_BASE_PWMC		0xfffb8000
+#define AT91SAM9263_BASE_EMAC		0xfffbc000
+#define AT91SAM9263_BASE_ISI		0xfffc4000
+#define AT91SAM9263_BASE_2DGE		0xfffc8000
+#define AT91_BASE_SYS			0xffffe000
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_ECC0	(0xffffe000 - AT91_BASE_SYS)
+#define AT91_SDRAMC0	(0xffffe200 - AT91_BASE_SYS)
+#define AT91_SMC0	(0xffffe400 - AT91_BASE_SYS)
+#define AT91_ECC1	(0xffffe600 - AT91_BASE_SYS)
+#define AT91_SDRAMC1	(0xffffe800 - AT91_BASE_SYS)
+#define AT91_SMC1	(0xffffea00 - AT91_BASE_SYS)
+#define AT91_MATRIX	(0xffffec00 - AT91_BASE_SYS)
+#define AT91_CCFG	(0xffffed10 - AT91_BASE_SYS)
+#define AT91_DBGU	(0xffffee00 - AT91_BASE_SYS)
+#define AT91_AIC	(0xfffff000 - AT91_BASE_SYS)
+#define AT91_PIOA	(0xfffff200 - AT91_BASE_SYS)
+#define AT91_PIOB	(0xfffff400 - AT91_BASE_SYS)
+#define AT91_PIOC	(0xfffff600 - AT91_BASE_SYS)
+#define AT91_PIOD	(0xfffff800 - AT91_BASE_SYS)
+#define AT91_PIOE	(0xfffffa00 - AT91_BASE_SYS)
+#define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
+#define AT91_RSTC	(0xfffffd00 - AT91_BASE_SYS)
+#define AT91_SHDWC	(0xfffffd10 - AT91_BASE_SYS)
+#define AT91_RTT0	(0xfffffd20 - AT91_BASE_SYS)
+#define AT91_PIT	(0xfffffd30 - AT91_BASE_SYS)
+#define AT91_WDT	(0xfffffd40 - AT91_BASE_SYS)
+#define AT91_RTT1	(0xfffffd50 - AT91_BASE_SYS)
+#define AT91_GPBR	(0xfffffd60 - AT91_BASE_SYS)
+
+#define AT91_SMC	AT91_SMC0
+
+/*
+ * Internal Memory.
+ */
+#define AT91SAM9263_SRAM0_BASE	0x00300000	/* Internal SRAM 0 base address */
+#define AT91SAM9263_SRAM0_SIZE	(80 * SZ_1K)	/* Internal SRAM 0 size (80Kb) */
+
+#define AT91SAM9263_ROM_BASE	0x00400000	/* Internal ROM base address */
+#define AT91SAM9263_ROM_SIZE	SZ_128K		/* Internal ROM size (128Kb) */
+
+#define AT91SAM9263_SRAM1_BASE	0x00500000	/* Internal SRAM 1 base address */
+#define AT91SAM9263_SRAM1_SIZE	SZ_16K		/* Internal SRAM 1 size (16Kb) */
+
+#define AT91SAM9263_LCDC_BASE	0x00700000	/* LCD Controller */
+#define AT91SAM9263_DMAC_BASE	0x00800000	/* DMA Controller */
+#define AT91SAM9263_UHP_BASE	0x00a00000	/* USB Host controller */
+
+#if 0
+/*
+ * PIO pin definitions (peripheral A/B multiplexing).
+ */
+
+// TODO: Add
+
+#endif
+
+#endif
diff --git a/include/asm-arm/arch-at91/at91sam9263_matrix.h b/include/asm-arm/arch-at91/at91sam9263_matrix.h
new file mode 100644
index 0000000..6fc6e4b
--- /dev/null
+++ b/include/asm-arm/arch-at91/at91sam9263_matrix.h
@@ -0,0 +1,129 @@
+/*
+ * include/asm-arm/arch-at91/at91sam9263_matrix.h
+ *
+ *  Copyright (C) 2006 Atmel Corporation.
+ *
+ * Memory Controllers (MATRIX, EBI) - System peripherals registers.
+ * Based on AT91SAM9263 datasheet revision B (Preliminary).
+ *
+ * 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.
+ */
+
+#ifndef AT91SAM9263_MATRIX_H
+#define AT91SAM9263_MATRIX_H
+
+#define AT91_MATRIX_MCFG0	(AT91_MATRIX + 0x00)	/* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1	(AT91_MATRIX + 0x04)	/* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2	(AT91_MATRIX + 0x08)	/* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3	(AT91_MATRIX + 0x0C)	/* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4	(AT91_MATRIX + 0x10)	/* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5	(AT91_MATRIX + 0x14)	/* Master Configuration Register 5 */
+#define AT91_MATRIX_MCFG6	(AT91_MATRIX + 0x18)	/* Master Configuration Register 6 */
+#define AT91_MATRIX_MCFG7	(AT91_MATRIX + 0x1C)	/* Master Configuration Register 7 */
+#define AT91_MATRIX_MCFG8	(AT91_MATRIX + 0x20)	/* Master Configuration Register 8 */
+#define		AT91_MATRIX_ULBT	(7 << 0)	/* Undefined Length Burst Type */
+#define			AT91_MATRIX_ULBT_INFINITE	(0 << 0)
+#define			AT91_MATRIX_ULBT_SINGLE		(1 << 0)
+#define			AT91_MATRIX_ULBT_FOUR		(2 << 0)
+#define			AT91_MATRIX_ULBT_EIGHT		(3 << 0)
+#define			AT91_MATRIX_ULBT_SIXTEEN	(4 << 0)
+
+#define AT91_MATRIX_SCFG0	(AT91_MATRIX + 0x40)	/* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1	(AT91_MATRIX + 0x44)	/* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2	(AT91_MATRIX + 0x48)	/* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3	(AT91_MATRIX + 0x4C)	/* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4	(AT91_MATRIX + 0x50)	/* Slave Configuration Register 4 */
+#define AT91_MATRIX_SCFG5	(AT91_MATRIX + 0x54)	/* Slave Configuration Register 5 */
+#define AT91_MATRIX_SCFG6	(AT91_MATRIX + 0x58)	/* Slave Configuration Register 6 */
+#define AT91_MATRIX_SCFG7	(AT91_MATRIX + 0x5C)	/* Slave Configuration Register 7 */
+#define		AT91_MATRIX_SLOT_CYCLE		(0xff << 0)	/* Maximum Number of Allowed Cycles for a Burst */
+#define		AT91_MATRIX_DEFMSTR_TYPE	(3    << 16)	/* Default Master Type */
+#define			AT91_MATRIX_DEFMSTR_TYPE_NONE	(0 << 16)
+#define			AT91_MATRIX_DEFMSTR_TYPE_LAST	(1 << 16)
+#define			AT91_MATRIX_DEFMSTR_TYPE_FIXED	(2 << 16)
+#define		AT91_MATRIX_FIXED_DEFMSTR	(7    << 18)	/* Fixed Index of Default Master */
+#define		AT91_MATRIX_ARBT		(3    << 24)	/* Arbitration Type */
+#define			AT91_MATRIX_ARBT_ROUND_ROBIN	(0 << 24)
+#define			AT91_MATRIX_ARBT_FIXED_PRIORITY	(1 << 24)
+
+#define AT91_MATRIX_PRAS0	(AT91_MATRIX + 0x80)	/* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRBS0	(AT91_MATRIX + 0x84)	/* Priority Register B for Slave 0 */
+#define AT91_MATRIX_PRAS1	(AT91_MATRIX + 0x88)	/* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRBS1	(AT91_MATRIX + 0x8C)	/* Priority Register B for Slave 1 */
+#define AT91_MATRIX_PRAS2	(AT91_MATRIX + 0x90)	/* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRBS2	(AT91_MATRIX + 0x94)	/* Priority Register B for Slave 2 */
+#define AT91_MATRIX_PRAS3	(AT91_MATRIX + 0x98)	/* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRBS3	(AT91_MATRIX + 0x9C)	/* Priority Register B for Slave 3 */
+#define AT91_MATRIX_PRAS4	(AT91_MATRIX + 0xA0)	/* Priority Register A for Slave 4 */
+#define AT91_MATRIX_PRBS4	(AT91_MATRIX + 0xA4)	/* Priority Register B for Slave 4 */
+#define AT91_MATRIX_PRAS5	(AT91_MATRIX + 0xA8)	/* Priority Register A for Slave 5 */
+#define AT91_MATRIX_PRBS5	(AT91_MATRIX + 0xAC)	/* Priority Register B for Slave 5 */
+#define AT91_MATRIX_PRAS6	(AT91_MATRIX + 0xB0)	/* Priority Register A for Slave 6 */
+#define AT91_MATRIX_PRBS6	(AT91_MATRIX + 0xB4)	/* Priority Register B for Slave 6 */
+#define AT91_MATRIX_PRAS7	(AT91_MATRIX + 0xB8)	/* Priority Register A for Slave 7 */
+#define AT91_MATRIX_PRBS7	(AT91_MATRIX + 0xBC)	/* Priority Register B for Slave 7 */
+#define		AT91_MATRIX_M0PR		(3 << 0)	/* Master 0 Priority */
+#define		AT91_MATRIX_M1PR		(3 << 4)	/* Master 1 Priority */
+#define		AT91_MATRIX_M2PR		(3 << 8)	/* Master 2 Priority */
+#define		AT91_MATRIX_M3PR		(3 << 12)	/* Master 3 Priority */
+#define		AT91_MATRIX_M4PR		(3 << 16)	/* Master 4 Priority */
+#define		AT91_MATRIX_M5PR		(3 << 20)	/* Master 5 Priority */
+#define		AT91_MATRIX_M6PR		(3 << 24)	/* Master 6 Priority */
+#define		AT91_MATRIX_M7PR		(3 << 28)	/* Master 7 Priority */
+#define		AT91_MATRIX_M8PR		(3 << 0)	/* Master 8 Priority (in Register B) */
+
+#define AT91_MATRIX_MRCR	(AT91_MATRIX + 0x100)	/* Master Remap Control Register */
+#define		AT91_MATRIX_RCB0		(1 << 0)	/* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
+#define		AT91_MATRIX_RCB1		(1 << 1)	/* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
+#define		AT91_MATRIX_RCB2		(1 << 2)
+#define		AT91_MATRIX_RCB3		(1 << 3)
+#define		AT91_MATRIX_RCB4		(1 << 4)
+#define		AT91_MATRIX_RCB5		(1 << 5)
+#define		AT91_MATRIX_RCB6		(1 << 6)
+#define		AT91_MATRIX_RCB7		(1 << 7)
+#define		AT91_MATRIX_RCB8		(1 << 8)
+
+#define AT91_MATRIX_TCMR	(AT91_MATRIX + 0x114)	/* TCM Configuration Register */
+#define		AT91_MATRIX_ITCM_SIZE		(0xf << 0)	/* Size of ITCM enabled memory block */
+#define			AT91_MATRIX_ITCM_0		(0 << 0)
+#define			AT91_MATRIX_ITCM_16		(5 << 0)
+#define			AT91_MATRIX_ITCM_32		(6 << 0)
+#define		AT91_MATRIX_DTCM_SIZE		(0xf << 4)	/* Size of DTCM enabled memory block */
+#define			AT91_MATRIX_DTCM_0		(0 << 4)
+#define			AT91_MATRIX_DTCM_16		(5 << 4)
+#define			AT91_MATRIX_DTCM_32		(6 << 4)
+
+#define AT91_MATRIX_EBI0CSA	(AT91_MATRIX + 0x120)	/* EBI0 Chip Select Assignment Register */
+#define		AT91_MATRIX_EBI0_CS1A		(1 << 1)	/* Chip Select 1 Assignment */
+#define			AT91_MATRIX_EBI0_CS1A_SMC		(0 << 1)
+#define			AT91_MATRIX_EBI0_CS1A_SDRAMC		(1 << 1)
+#define		AT91_MATRIX_EBI0_CS3A		(1 << 3)	/* Chip Select 3 Assignment */
+#define			AT91_MATRIX_EBI0_CS3A_SMC		(0 << 3)
+#define			AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA	(1 << 3)
+#define		AT91_MATRIX_EBI0_CS4A		(1 << 4)	/* Chip Select 4 Assignment */
+#define			AT91_MATRIX_EBI0_CS4A_SMC		(0 << 4)
+#define			AT91_MATRIX_EBI0_CS4A_SMC_CF1		(1 << 4)
+#define		AT91_MATRIX_EBI0_CS5A		(1 << 5)	/* Chip Select 5 Assignment */
+#define			AT91_MATRIX_EBI0_CS5A_SMC		(0 << 5)
+#define			AT91_MATRIX_EBI0_CS5A_SMC_CF2		(1 << 5)
+#define		AT91_MATRIX_EBI0_DBPUC		(1 << 8)	/* Data Bus Pull-up Configuration */
+#define		AT91_MATRIX_EBI0_VDDIOMSEL	(1 << 16)	/* Memory voltage selection */
+#define			AT91_MATRIX_EBI0_VDDIOMSEL_1_8V		(0 << 16)
+#define			AT91_MATRIX_EBI0_VDDIOMSEL_3_3V		(1 << 16)
+
+#define AT91_MATRIX_EBI1CSA	(AT91_MATRIX + 0x124)	/* EBI1 Chip Select Assignment Register */
+#define		AT91_MATRIX_EBI1_CS1A		(1 << 1)	/* Chip Select 1 Assignment */
+#define			AT91_MATRIX_EBI1_CS1A_SMC		(0 << 1)
+#define			AT91_MATRIX_EBI1_CS1A_SDRAMC		(1 << 1)
+#define		AT91_MATRIX_EBI1_CS2A		(1 << 3)	/* Chip Select 3 Assignment */
+#define			AT91_MATRIX_EBI1_CS2A_SMC		(0 << 3)
+#define			AT91_MATRIX_EBI1_CS2A_SMC_SMARTMEDIA	(1 << 3)
+#define		AT91_MATRIX_EBI1_DBPUC		(1 << 8)	/* Data Bus Pull-up Configuration */
+#define		AT91_MATRIX_EBI1_VDDIOMSEL	(1 << 16)	/* Memory voltage selection */
+#define			AT91_MATRIX_EBI1_VDDIOMSEL_1_8V		(0 << 16)
+#define			AT91_MATRIX_EBI1_VDDIOMSEL_3_3V		(1 << 16)
+
+#endif
diff --git a/include/asm-arm/arch-at91rm9200/at91sam926x_mc.h b/include/asm-arm/arch-at91/at91sam926x_mc.h
similarity index 92%
rename from include/asm-arm/arch-at91rm9200/at91sam926x_mc.h
rename to include/asm-arm/arch-at91/at91sam926x_mc.h
index 972e753..d82631c 100644
--- a/include/asm-arm/arch-at91rm9200/at91sam926x_mc.h
+++ b/include/asm-arm/arch-at91/at91sam926x_mc.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/at91sam926x_mc.h
+ * include/asm-arm/arch-at91/at91sam926x_mc.h
  *
  * Memory Controllers (SMC, SDRAMC) - System peripherals registers.
  * Based on AT91SAM9261 datasheet revision D.
@@ -131,4 +131,11 @@
 #define			AT91_SMC_PS_16			(2 << 28)
 #define			AT91_SMC_PS_32			(3 << 28)
 
+#if defined(AT91_SMC1)		/* The AT91SAM9263 has 2 Static Memory contollers */
+#define AT91_SMC1_SETUP(n)	(AT91_SMC1 + 0x00 + ((n)*0x10))	/* Setup Register for CS n */
+#define AT91_SMC1_PULSE(n)	(AT91_SMC1 + 0x04 + ((n)*0x10))	/* Pulse Register for CS n */
+#define AT91_SMC1_CYCLE(n)	(AT91_SMC1 + 0x08 + ((n)*0x10))	/* Cycle Register for CS n */
+#define AT91_SMC1_MODE(n)	(AT91_SMC1 + 0x0c + ((n)*0x10))	/* Mode Register for CS n */
+#endif
+
 #endif
diff --git a/include/asm-arm/arch-at91rm9200/board.h b/include/asm-arm/arch-at91/board.h
similarity index 92%
rename from include/asm-arm/arch-at91rm9200/board.h
rename to include/asm-arm/arch-at91/board.h
index 768e0fc..7b9903c 100644
--- a/include/asm-arm/arch-at91rm9200/board.h
+++ b/include/asm-arm/arch-at91/board.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/board.h
+ * include/asm-arm/arch-at91/board.h
  *
  *  Copyright (C) 2005 HP Labs
  *
@@ -60,7 +60,7 @@
 	u8		wp_pin;		/* (SD) writeprotect detect */
 	u8		vcc_pin;	/* power switching (high == on) */
 };
-extern void __init at91_add_device_mmc(struct at91_mmc_data *data);
+extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data);
 
  /* Ethernet */
 struct at91_eth_data {
@@ -69,9 +69,14 @@
 };
 extern void __init at91_add_device_eth(struct at91_eth_data *data);
 
+#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263)
+#define eth_platform_data	at91_eth_data
+#endif
+
  /* USB Host */
 struct at91_usbh_data {
 	u8		ports;		/* number of ports on root hub */
+	u8		vbus_pin[];	/* port power-control pin */
 };
 extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
 
diff --git a/include/asm-arm/arch-at91/cpu.h b/include/asm-arm/arch-at91/cpu.h
new file mode 100644
index 0000000..d464ca5
--- /dev/null
+++ b/include/asm-arm/arch-at91/cpu.h
@@ -0,0 +1,71 @@
+/*
+ * include/asm-arm/arch-at91/cpu.h
+ *
+ *  Copyright (C) 2006 SAN People
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_CPU_H
+#define __ASM_ARCH_CPU_H
+
+#include <asm/hardware.h>
+#include <asm/arch/at91_dbgu.h>
+
+
+#define ARCH_ID_AT91RM9200	0x09290780
+#define ARCH_ID_AT91SAM9260	0x019803a0
+#define ARCH_ID_AT91SAM9261	0x019703a0
+#define ARCH_ID_AT91SAM9263	0x019607a0
+
+#define ARCH_ID_AT91SAM9XE128	0x329973a0
+#define ARCH_ID_AT91SAM9XE256	0x329a93a0
+#define ARCH_ID_AT91SAM9XE512	0x329aa3a0
+
+static inline unsigned long at91_cpu_identify(void)
+{
+	return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION);
+}
+
+
+#define ARCH_FAMILY_AT91X92	0x09200000
+#define ARCH_FAMILY_AT91SAM9	0x01900000
+#define ARCH_FAMILY_AT91SAM9XE	0x02900000
+
+static inline unsigned long at91_arch_identify(void)
+{
+	return (at91_sys_read(AT91_DBGU_CIDR) & AT91_CIDR_ARCH);
+}
+
+
+#ifdef CONFIG_ARCH_AT91RM9200
+#define cpu_is_at91rm9200()	(at91_cpu_identify() == ARCH_ID_AT91RM9200)
+#else
+#define cpu_is_at91rm9200()	(0)
+#endif
+
+#ifdef CONFIG_ARCH_AT91SAM9260
+#define cpu_is_at91sam9xe()	(at91_arch_identify() == ARCH_FAMILY_AT91SAM9XE)
+#define cpu_is_at91sam9260()	((at91_cpu_identify() == ARCH_ID_AT91SAM9260) || cpu_is_at91sam9xe())
+#else
+#define cpu_is_at91sam9xe()	(0)
+#define cpu_is_at91sam9260()	(0)
+#endif
+
+#ifdef CONFIG_ARCH_AT91SAM9261
+#define cpu_is_at91sam9261()	(at91_cpu_identify() == ARCH_ID_AT91SAM9261)
+#else
+#define cpu_is_at91sam9261()	(0)
+#endif
+
+#ifdef CONFIG_ARCH_AT91SAM9263
+#define cpu_is_at91sam9263()	(at91_cpu_identify() == ARCH_ID_AT91SAM9263)
+#else
+#define cpu_is_at91sam9263()	(0)
+#endif
+
+#endif
diff --git a/include/asm-arm/arch-at91/debug-macro.S b/include/asm-arm/arch-at91/debug-macro.S
new file mode 100644
index 0000000..13e9f5e
--- /dev/null
+++ b/include/asm-arm/arch-at91/debug-macro.S
@@ -0,0 +1,39 @@
+/*
+ * include/asm-arm/arch-at91/debug-macro.S
+ *
+ *  Copyright (C) 2003-2005 SAN People
+ *
+ * Debugging macro include header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <asm/hardware.h>
+#include <asm/arch/at91_dbgu.h>
+
+	.macro	addruart,rx
+	mrc	p15, 0, \rx, c1, c0
+	tst	\rx, #1						@ MMU enabled?
+	ldreq	\rx, =(AT91_BASE_SYS + AT91_DBGU)		@ System peripherals (phys address)
+	ldrne	\rx, =(AT91_VA_BASE_SYS	+ AT91_DBGU)		@ System peripherals (virt address)
+	.endm
+
+	.macro	senduart,rd,rx
+	strb	\rd, [\rx, #(AT91_DBGU_THR - AT91_DBGU)]	@ Write to Transmitter Holding Register
+	.endm
+
+	.macro	waituart,rd,rx
+1001:	ldr	\rd, [\rx, #(AT91_DBGU_SR - AT91_DBGU)]		@ Read Status Register
+	tst	\rd, #AT91_DBGU_TXRDY				@ DBGU_TXRDY = 1 when ready to transmit
+	beq	1001b
+	.endm
+
+	.macro	busyuart,rd,rx
+1001:	ldr	\rd, [\rx, #(AT91_DBGU_SR - AT91_DBGU)]		@ Read Status Register
+	tst	\rd, #AT91_DBGU_TXEMPTY				@ DBGU_TXEMPTY = 1 when transmission complete
+	beq	1001b
+	.endm
+
diff --git a/include/asm-arm/arch-at91rm9200/dma.h b/include/asm-arm/arch-at91/dma.h
similarity index 94%
rename from include/asm-arm/arch-at91rm9200/dma.h
rename to include/asm-arm/arch-at91/dma.h
index 22c1dfd..7745654 100644
--- a/include/asm-arm/arch-at91rm9200/dma.h
+++ b/include/asm-arm/arch-at91/dma.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/dma.h
+ * include/asm-arm/arch-at91/dma.h
  *
  *  Copyright (C) 2003 SAN People
  *
diff --git a/include/asm-arm/arch-at91/entry-macro.S b/include/asm-arm/arch-at91/entry-macro.S
new file mode 100644
index 0000000..76c8ccc
--- /dev/null
+++ b/include/asm-arm/arch-at91/entry-macro.S
@@ -0,0 +1,26 @@
+/*
+ * include/asm-arm/arch-at91/entry-macro.S
+ *
+ *  Copyright (C) 2003-2005 SAN People
+ *
+ * Low-level IRQ helper macros for AT91RM9200 platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/hardware.h>
+#include <asm/arch/at91_aic.h>
+
+	.macro	disable_fiq
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+	ldr	\base, =(AT91_VA_BASE_SYS + AT91_AIC)		@ base virtual address of AIC peripheral
+	ldr	\irqnr, [\base, #(AT91_AIC_IVR - AT91_AIC)]	@ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt)
+	ldr	\irqstat, [\base, #(AT91_AIC_ISR - AT91_AIC)]	@ read interrupt source number
+	teq	\irqstat, #0					@ ISR is 0 when no current interrupt, or spurious interrupt
+	streq	\tmp, [\base, #(AT91_AIC_EOICR - AT91_AIC)]	@ not going to be handled further, then ACK it now.
+	.endm
+
diff --git a/include/asm-arm/arch-at91rm9200/gpio.h b/include/asm-arm/arch-at91/gpio.h
similarity index 84%
rename from include/asm-arm/arch-at91rm9200/gpio.h
rename to include/asm-arm/arch-at91/gpio.h
index e09d652..98ad211 100644
--- a/include/asm-arm/arch-at91rm9200/gpio.h
+++ b/include/asm-arm/arch-at91/gpio.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/gpio.h
+ * include/asm-arm/arch-at91/gpio.h
  *
  *  Copyright (C) 2005 HP Labs
  *
@@ -17,7 +17,7 @@
 
 #define PIN_BASE		NR_AIC_IRQS
 
-#define MAX_GPIO_BANKS		4
+#define MAX_GPIO_BANKS		5
 
 /* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */
 
@@ -26,37 +26,31 @@
 #define	AT91_PIN_PA2	(PIN_BASE + 0x00 + 2)
 #define	AT91_PIN_PA3	(PIN_BASE + 0x00 + 3)
 #define	AT91_PIN_PA4	(PIN_BASE + 0x00 + 4)
-
 #define	AT91_PIN_PA5	(PIN_BASE + 0x00 + 5)
 #define	AT91_PIN_PA6	(PIN_BASE + 0x00 + 6)
 #define	AT91_PIN_PA7	(PIN_BASE + 0x00 + 7)
 #define	AT91_PIN_PA8	(PIN_BASE + 0x00 + 8)
 #define	AT91_PIN_PA9	(PIN_BASE + 0x00 + 9)
-
 #define	AT91_PIN_PA10	(PIN_BASE + 0x00 + 10)
 #define	AT91_PIN_PA11	(PIN_BASE + 0x00 + 11)
 #define	AT91_PIN_PA12	(PIN_BASE + 0x00 + 12)
 #define	AT91_PIN_PA13	(PIN_BASE + 0x00 + 13)
 #define	AT91_PIN_PA14	(PIN_BASE + 0x00 + 14)
-
 #define	AT91_PIN_PA15	(PIN_BASE + 0x00 + 15)
 #define	AT91_PIN_PA16	(PIN_BASE + 0x00 + 16)
 #define	AT91_PIN_PA17	(PIN_BASE + 0x00 + 17)
 #define	AT91_PIN_PA18	(PIN_BASE + 0x00 + 18)
 #define	AT91_PIN_PA19	(PIN_BASE + 0x00 + 19)
-
 #define	AT91_PIN_PA20	(PIN_BASE + 0x00 + 20)
 #define	AT91_PIN_PA21	(PIN_BASE + 0x00 + 21)
 #define	AT91_PIN_PA22	(PIN_BASE + 0x00 + 22)
 #define	AT91_PIN_PA23	(PIN_BASE + 0x00 + 23)
 #define	AT91_PIN_PA24	(PIN_BASE + 0x00 + 24)
-
 #define	AT91_PIN_PA25	(PIN_BASE + 0x00 + 25)
 #define	AT91_PIN_PA26	(PIN_BASE + 0x00 + 26)
 #define	AT91_PIN_PA27	(PIN_BASE + 0x00 + 27)
 #define	AT91_PIN_PA28	(PIN_BASE + 0x00 + 28)
 #define	AT91_PIN_PA29	(PIN_BASE + 0x00 + 29)
-
 #define	AT91_PIN_PA30	(PIN_BASE + 0x00 + 30)
 #define	AT91_PIN_PA31	(PIN_BASE + 0x00 + 31)
 
@@ -65,37 +59,31 @@
 #define	AT91_PIN_PB2	(PIN_BASE + 0x20 + 2)
 #define	AT91_PIN_PB3	(PIN_BASE + 0x20 + 3)
 #define	AT91_PIN_PB4	(PIN_BASE + 0x20 + 4)
-
 #define	AT91_PIN_PB5	(PIN_BASE + 0x20 + 5)
 #define	AT91_PIN_PB6	(PIN_BASE + 0x20 + 6)
 #define	AT91_PIN_PB7	(PIN_BASE + 0x20 + 7)
 #define	AT91_PIN_PB8	(PIN_BASE + 0x20 + 8)
 #define	AT91_PIN_PB9	(PIN_BASE + 0x20 + 9)
-
 #define	AT91_PIN_PB10	(PIN_BASE + 0x20 + 10)
 #define	AT91_PIN_PB11	(PIN_BASE + 0x20 + 11)
 #define	AT91_PIN_PB12	(PIN_BASE + 0x20 + 12)
 #define	AT91_PIN_PB13	(PIN_BASE + 0x20 + 13)
 #define	AT91_PIN_PB14	(PIN_BASE + 0x20 + 14)
-
 #define	AT91_PIN_PB15	(PIN_BASE + 0x20 + 15)
 #define	AT91_PIN_PB16	(PIN_BASE + 0x20 + 16)
 #define	AT91_PIN_PB17	(PIN_BASE + 0x20 + 17)
 #define	AT91_PIN_PB18	(PIN_BASE + 0x20 + 18)
 #define	AT91_PIN_PB19	(PIN_BASE + 0x20 + 19)
-
 #define	AT91_PIN_PB20	(PIN_BASE + 0x20 + 20)
 #define	AT91_PIN_PB21	(PIN_BASE + 0x20 + 21)
 #define	AT91_PIN_PB22	(PIN_BASE + 0x20 + 22)
 #define	AT91_PIN_PB23	(PIN_BASE + 0x20 + 23)
 #define	AT91_PIN_PB24	(PIN_BASE + 0x20 + 24)
-
 #define	AT91_PIN_PB25	(PIN_BASE + 0x20 + 25)
 #define	AT91_PIN_PB26	(PIN_BASE + 0x20 + 26)
 #define	AT91_PIN_PB27	(PIN_BASE + 0x20 + 27)
 #define	AT91_PIN_PB28	(PIN_BASE + 0x20 + 28)
 #define	AT91_PIN_PB29	(PIN_BASE + 0x20 + 29)
-
 #define	AT91_PIN_PB30	(PIN_BASE + 0x20 + 30)
 #define	AT91_PIN_PB31	(PIN_BASE + 0x20 + 31)
 
@@ -104,37 +92,31 @@
 #define	AT91_PIN_PC2	(PIN_BASE + 0x40 + 2)
 #define	AT91_PIN_PC3	(PIN_BASE + 0x40 + 3)
 #define	AT91_PIN_PC4	(PIN_BASE + 0x40 + 4)
-
 #define	AT91_PIN_PC5	(PIN_BASE + 0x40 + 5)
 #define	AT91_PIN_PC6	(PIN_BASE + 0x40 + 6)
 #define	AT91_PIN_PC7	(PIN_BASE + 0x40 + 7)
 #define	AT91_PIN_PC8	(PIN_BASE + 0x40 + 8)
 #define	AT91_PIN_PC9	(PIN_BASE + 0x40 + 9)
-
 #define	AT91_PIN_PC10	(PIN_BASE + 0x40 + 10)
 #define	AT91_PIN_PC11	(PIN_BASE + 0x40 + 11)
 #define	AT91_PIN_PC12	(PIN_BASE + 0x40 + 12)
 #define	AT91_PIN_PC13	(PIN_BASE + 0x40 + 13)
 #define	AT91_PIN_PC14	(PIN_BASE + 0x40 + 14)
-
 #define	AT91_PIN_PC15	(PIN_BASE + 0x40 + 15)
 #define	AT91_PIN_PC16	(PIN_BASE + 0x40 + 16)
 #define	AT91_PIN_PC17	(PIN_BASE + 0x40 + 17)
 #define	AT91_PIN_PC18	(PIN_BASE + 0x40 + 18)
 #define	AT91_PIN_PC19	(PIN_BASE + 0x40 + 19)
-
 #define	AT91_PIN_PC20	(PIN_BASE + 0x40 + 20)
 #define	AT91_PIN_PC21	(PIN_BASE + 0x40 + 21)
 #define	AT91_PIN_PC22	(PIN_BASE + 0x40 + 22)
 #define	AT91_PIN_PC23	(PIN_BASE + 0x40 + 23)
 #define	AT91_PIN_PC24	(PIN_BASE + 0x40 + 24)
-
 #define	AT91_PIN_PC25	(PIN_BASE + 0x40 + 25)
 #define	AT91_PIN_PC26	(PIN_BASE + 0x40 + 26)
 #define	AT91_PIN_PC27	(PIN_BASE + 0x40 + 27)
 #define	AT91_PIN_PC28	(PIN_BASE + 0x40 + 28)
 #define	AT91_PIN_PC29	(PIN_BASE + 0x40 + 29)
-
 #define	AT91_PIN_PC30	(PIN_BASE + 0x40 + 30)
 #define	AT91_PIN_PC31	(PIN_BASE + 0x40 + 31)
 
@@ -143,40 +125,67 @@
 #define	AT91_PIN_PD2	(PIN_BASE + 0x60 + 2)
 #define	AT91_PIN_PD3	(PIN_BASE + 0x60 + 3)
 #define	AT91_PIN_PD4	(PIN_BASE + 0x60 + 4)
-
 #define	AT91_PIN_PD5	(PIN_BASE + 0x60 + 5)
 #define	AT91_PIN_PD6	(PIN_BASE + 0x60 + 6)
 #define	AT91_PIN_PD7	(PIN_BASE + 0x60 + 7)
 #define	AT91_PIN_PD8	(PIN_BASE + 0x60 + 8)
 #define	AT91_PIN_PD9	(PIN_BASE + 0x60 + 9)
-
 #define	AT91_PIN_PD10	(PIN_BASE + 0x60 + 10)
 #define	AT91_PIN_PD11	(PIN_BASE + 0x60 + 11)
 #define	AT91_PIN_PD12	(PIN_BASE + 0x60 + 12)
 #define	AT91_PIN_PD13	(PIN_BASE + 0x60 + 13)
 #define	AT91_PIN_PD14	(PIN_BASE + 0x60 + 14)
-
 #define	AT91_PIN_PD15	(PIN_BASE + 0x60 + 15)
 #define	AT91_PIN_PD16	(PIN_BASE + 0x60 + 16)
 #define	AT91_PIN_PD17	(PIN_BASE + 0x60 + 17)
 #define	AT91_PIN_PD18	(PIN_BASE + 0x60 + 18)
 #define	AT91_PIN_PD19	(PIN_BASE + 0x60 + 19)
-
 #define	AT91_PIN_PD20	(PIN_BASE + 0x60 + 20)
 #define	AT91_PIN_PD21	(PIN_BASE + 0x60 + 21)
 #define	AT91_PIN_PD22	(PIN_BASE + 0x60 + 22)
 #define	AT91_PIN_PD23	(PIN_BASE + 0x60 + 23)
 #define	AT91_PIN_PD24	(PIN_BASE + 0x60 + 24)
-
 #define	AT91_PIN_PD25	(PIN_BASE + 0x60 + 25)
 #define	AT91_PIN_PD26	(PIN_BASE + 0x60 + 26)
 #define	AT91_PIN_PD27	(PIN_BASE + 0x60 + 27)
 #define	AT91_PIN_PD28	(PIN_BASE + 0x60 + 28)
 #define	AT91_PIN_PD29	(PIN_BASE + 0x60 + 29)
-
 #define	AT91_PIN_PD30	(PIN_BASE + 0x60 + 30)
 #define	AT91_PIN_PD31	(PIN_BASE + 0x60 + 31)
 
+#define	AT91_PIN_PE0	(PIN_BASE + 0x80 + 0)
+#define	AT91_PIN_PE1	(PIN_BASE + 0x80 + 1)
+#define	AT91_PIN_PE2	(PIN_BASE + 0x80 + 2)
+#define	AT91_PIN_PE3	(PIN_BASE + 0x80 + 3)
+#define	AT91_PIN_PE4	(PIN_BASE + 0x80 + 4)
+#define	AT91_PIN_PE5	(PIN_BASE + 0x80 + 5)
+#define	AT91_PIN_PE6	(PIN_BASE + 0x80 + 6)
+#define	AT91_PIN_PE7	(PIN_BASE + 0x80 + 7)
+#define	AT91_PIN_PE8	(PIN_BASE + 0x80 + 8)
+#define	AT91_PIN_PE9	(PIN_BASE + 0x80 + 9)
+#define	AT91_PIN_PE10	(PIN_BASE + 0x80 + 10)
+#define	AT91_PIN_PE11	(PIN_BASE + 0x80 + 11)
+#define	AT91_PIN_PE12	(PIN_BASE + 0x80 + 12)
+#define	AT91_PIN_PE13	(PIN_BASE + 0x80 + 13)
+#define	AT91_PIN_PE14	(PIN_BASE + 0x80 + 14)
+#define	AT91_PIN_PE15	(PIN_BASE + 0x80 + 15)
+#define	AT91_PIN_PE16	(PIN_BASE + 0x80 + 16)
+#define	AT91_PIN_PE17	(PIN_BASE + 0x80 + 17)
+#define	AT91_PIN_PE18	(PIN_BASE + 0x80 + 18)
+#define	AT91_PIN_PE19	(PIN_BASE + 0x80 + 19)
+#define	AT91_PIN_PE20	(PIN_BASE + 0x80 + 20)
+#define	AT91_PIN_PE21	(PIN_BASE + 0x80 + 21)
+#define	AT91_PIN_PE22	(PIN_BASE + 0x80 + 22)
+#define	AT91_PIN_PE23	(PIN_BASE + 0x80 + 23)
+#define	AT91_PIN_PE24	(PIN_BASE + 0x80 + 24)
+#define	AT91_PIN_PE25	(PIN_BASE + 0x80 + 25)
+#define	AT91_PIN_PE26	(PIN_BASE + 0x80 + 26)
+#define	AT91_PIN_PE27	(PIN_BASE + 0x80 + 27)
+#define	AT91_PIN_PE28	(PIN_BASE + 0x80 + 28)
+#define	AT91_PIN_PE29	(PIN_BASE + 0x80 + 29)
+#define	AT91_PIN_PE30	(PIN_BASE + 0x80 + 30)
+#define	AT91_PIN_PE31	(PIN_BASE + 0x80 + 31)
+
 #ifndef __ASSEMBLY__
 /* setup setup routines, called from board init or driver probe() */
 extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup);
diff --git a/include/asm-arm/arch-at91rm9200/hardware.h b/include/asm-arm/arch-at91/hardware.h
similarity index 86%
rename from include/asm-arm/arch-at91rm9200/hardware.h
rename to include/asm-arm/arch-at91/hardware.h
index 9ea5bfe..eaaf1c1 100644
--- a/include/asm-arm/arch-at91rm9200/hardware.h
+++ b/include/asm-arm/arch-at91/hardware.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/hardware.h
+ * include/asm-arm/arch-at91/hardware.h
  *
  *  Copyright (C) 2003 SAN People
  *  Copyright (C) 2003 ATMEL
@@ -22,21 +22,23 @@
 #include <asm/arch/at91sam9260.h>
 #elif defined(CONFIG_ARCH_AT91SAM9261)
 #include <asm/arch/at91sam9261.h>
+#elif defined(CONFIG_ARCH_AT91SAM9263)
+#include <asm/arch/at91sam9263.h>
 #else
 #error "Unsupported AT91 processor"
 #endif
 
 
 /*
- * Remap the peripherals from address 0xFFFA0000 .. 0xFFFFFFFF
- * to 0xFEFA0000 .. 0xFF000000.  (384Kb)
+ * Remap the peripherals from address 0xFFF78000 .. 0xFFFFFFFF
+ * to 0xFEF78000 .. 0xFF000000.  (5444Kb)
  */
-#define AT91_IO_PHYS_BASE	0xFFFA0000
+#define AT91_IO_PHYS_BASE	0xFFF78000
 #define AT91_IO_SIZE		(0xFFFFFFFF - AT91_IO_PHYS_BASE + 1)
 #define AT91_IO_VIRT_BASE	(0xFF000000 - AT91_IO_SIZE)
 
  /* Convert a physical IO address to virtual IO address */
-#define AT91_IO_P2V(x)	((x) - AT91_IO_PHYS_BASE + AT91_IO_VIRT_BASE)
+#define AT91_IO_P2V(x)		((x) - AT91_IO_PHYS_BASE + AT91_IO_VIRT_BASE)
 
 /*
  * Virtual to Physical Address mapping for IO devices.
diff --git a/include/asm-arm/arch-at91rm9200/io.h b/include/asm-arm/arch-at91/io.h
similarity index 95%
rename from include/asm-arm/arch-at91rm9200/io.h
rename to include/asm-arm/arch-at91/io.h
index 88fd1be..401f327 100644
--- a/include/asm-arm/arch-at91rm9200/io.h
+++ b/include/asm-arm/arch-at91/io.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/io.h
+ * include/asm-arm/arch-at91/io.h
  *
  *  Copyright (C) 2003 SAN People
  *
diff --git a/include/asm-arm/arch-at91rm9200/irqs.h b/include/asm-arm/arch-at91/irqs.h
similarity index 90%
rename from include/asm-arm/arch-at91rm9200/irqs.h
rename to include/asm-arm/arch-at91/irqs.h
index c0679ea..1ffa3bb 100644
--- a/include/asm-arm/arch-at91rm9200/irqs.h
+++ b/include/asm-arm/arch-at91/irqs.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/irqs.h
+ * include/asm-arm/arch-at91/irqs.h
  *
  *  Copyright (C) 2004 SAN People
  *
@@ -37,8 +37,8 @@
  * IRQ interrupt symbols are the AT91xxx_ID_* symbols
  * for IRQs handled directly through the AIC, or else the AT91_PIN_*
  * symbols in gpio.h for ones handled indirectly as GPIOs.
- * We make provision for 4 banks of GPIO.
+ * We make provision for 5 banks of GPIO.
  */
-#define	NR_IRQS		(NR_AIC_IRQS + (4 * 32))
+#define	NR_IRQS		(NR_AIC_IRQS + (5 * 32))
 
 #endif
diff --git a/include/asm-arm/arch-at91rm9200/memory.h b/include/asm-arm/arch-at91/memory.h
similarity index 96%
rename from include/asm-arm/arch-at91rm9200/memory.h
rename to include/asm-arm/arch-at91/memory.h
index f985069..4835d67 100644
--- a/include/asm-arm/arch-at91rm9200/memory.h
+++ b/include/asm-arm/arch-at91/memory.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/memory.h
+ * include/asm-arm/arch-at91/memory.h
  *
  *  Copyright (C) 2004 SAN People
  *
diff --git a/include/asm-arm/arch-at91rm9200/system.h b/include/asm-arm/arch-at91/system.h
similarity index 96%
rename from include/asm-arm/arch-at91rm9200/system.h
rename to include/asm-arm/arch-at91/system.h
index 9c67130..6bf8460 100644
--- a/include/asm-arm/arch-at91rm9200/system.h
+++ b/include/asm-arm/arch-at91/system.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/system.h
+ * include/asm-arm/arch-at91/system.h
  *
  *  Copyright (C) 2003 SAN People
  *
diff --git a/include/asm-arm/arch-at91rm9200/timex.h b/include/asm-arm/arch-at91/timex.h
similarity index 86%
rename from include/asm-arm/arch-at91rm9200/timex.h
rename to include/asm-arm/arch-at91/timex.h
index faeca45..f41636d 100644
--- a/include/asm-arm/arch-at91rm9200/timex.h
+++ b/include/asm-arm/arch-at91/timex.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/timex.h
+ * include/asm-arm/arch-at91/timex.h
  *
  *  Copyright (C) 2003 SAN People
  *
@@ -32,6 +32,11 @@
 #define AT91SAM9_MASTER_CLOCK	99300000
 #define CLOCK_TICK_RATE		(AT91SAM9_MASTER_CLOCK/16)
 
+#elif defined(CONFIG_ARCH_AT91SAM9263)
+
+#define AT91SAM9_MASTER_CLOCK	99959500
+#define CLOCK_TICK_RATE		(AT91SAM9_MASTER_CLOCK/16)
+
 #endif
 
 #endif
diff --git a/include/asm-arm/arch-at91rm9200/uncompress.h b/include/asm-arm/arch-at91/uncompress.h
similarity index 96%
rename from include/asm-arm/arch-at91rm9200/uncompress.h
rename to include/asm-arm/arch-at91/uncompress.h
index 34b4b93..a193d28 100644
--- a/include/asm-arm/arch-at91rm9200/uncompress.h
+++ b/include/asm-arm/arch-at91/uncompress.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/uncompress.h
+ * include/asm-arm/arch-at91/uncompress.h
  *
  *  Copyright (C) 2003 SAN People
  *
diff --git a/include/asm-arm/arch-at91rm9200/vmalloc.h b/include/asm-arm/arch-at91/vmalloc.h
similarity index 94%
rename from include/asm-arm/arch-at91rm9200/vmalloc.h
rename to include/asm-arm/arch-at91/vmalloc.h
index 0a23b8c..bb05e70 100644
--- a/include/asm-arm/arch-at91rm9200/vmalloc.h
+++ b/include/asm-arm/arch-at91/vmalloc.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-at91rm9200/vmalloc.h
+ * include/asm-arm/arch-at91/vmalloc.h
  *
  *  Copyright (C) 2003 SAN People
  *
diff --git a/include/asm-arm/arch-at91rm9200/at91_pdc.h b/include/asm-arm/arch-at91rm9200/at91_pdc.h
deleted file mode 100644
index 79d6e02..0000000
--- a/include/asm-arm/arch-at91rm9200/at91_pdc.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * include/asm-arm/arch-at91rm9200/at91_pdc.h
- *
- * Copyright (C) 2005 Ivan Kokshaysky
- * Copyright (C) SAN People
- *
- * Peripheral Data Controller (PDC) registers.
- * Based on AT91RM9200 datasheet revision E.
- *
- * 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.
- */
-
-#ifndef AT91_PDC_H
-#define AT91_PDC_H
-
-#define AT91_PDC_RPR		0x100	/* Receive Pointer Register */
-#define AT91_PDC_RCR		0x104	/* Receive Counter Register */
-#define AT91_PDC_TPR		0x108	/* Transmit Pointer Register */
-#define AT91_PDC_TCR		0x10c	/* Transmit Counter Register */
-#define AT91_PDC_RNPR		0x110	/* Receive Next Pointer Register */
-#define AT91_PDC_RNCR		0x114	/* Receive Next Counter Register */
-#define AT91_PDC_TNPR		0x118	/* Transmit Next Pointer Register */
-#define AT91_PDC_TNCR		0x11c	/* Transmit Next Counter Register */
-
-#define AT91_PDC_PTCR		0x120	/* Transfer Control Register */
-#define		AT91_PDC_RXTEN		(1 << 0)	/* Receiver Transfer Enable */
-#define		AT91_PDC_RXTDIS		(1 << 1)	/* Receiver Transfer Disable */
-#define		AT91_PDC_TXTEN		(1 << 8)	/* Transmitter Transfer Enable */
-#define		AT91_PDC_TXTDIS		(1 << 9)	/* Transmitter Transfer Disable */
-
-#define AT91_PDC_PTSR		0x124	/* Transfer Status Register */
-
-#endif
diff --git a/include/asm-arm/arch-at91rm9200/cpu.h b/include/asm-arm/arch-at91rm9200/cpu.h
deleted file mode 100644
index 6f8d09b..0000000
--- a/include/asm-arm/arch-at91rm9200/cpu.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * include/asm-arm/arch-at91rm9200/cpu.h
- *
- *  Copyright (C) 2006 SAN People
- *
- * 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.
- *
- */
-
-#ifndef __ASM_ARCH_CPU_H
-#define __ASM_ARCH_CPU_H
-
-#include <asm/hardware.h>
-#include <asm/arch/at91_dbgu.h>
-
-
-#define ARCH_ID_AT91RM9200	0x09290780
-#define ARCH_ID_AT91SAM9260	0x019803a0
-#define ARCH_ID_AT91SAM9261	0x019703a0
-
-
-static inline unsigned long at91_cpu_identify(void)
-{
-	return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION);
-}
-
-
-#ifdef CONFIG_ARCH_AT91RM9200
-#define cpu_is_at91rm9200()	(at91_cpu_identify() == ARCH_ID_AT91RM9200)
-#else
-#define cpu_is_at91rm9200()	(0)
-#endif
-
-#ifdef CONFIG_ARCH_AT91SAM9260
-#define cpu_is_at91sam9260()	(at91_cpu_identify() == ARCH_ID_AT91SAM9260)
-#else
-#define cpu_is_at91sam9260()	(0)
-#endif
-
-#ifdef CONFIG_ARCH_AT91SAM9261
-#define cpu_is_at91sam9261()	(at91_cpu_identify() == ARCH_ID_AT91SAM9261)
-#else
-#define cpu_is_at91sam9261()	(0)
-#endif
-
-#endif
diff --git a/include/asm-arm/arch-at91rm9200/debug-macro.S b/include/asm-arm/arch-at91rm9200/debug-macro.S
deleted file mode 100644
index 85cdadf..0000000
--- a/include/asm-arm/arch-at91rm9200/debug-macro.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * include/asm-arm/arch-at91rm9200/debug-macro.S
- *
- *  Copyright (C) 2003-2005 SAN People
- *
- * Debugging macro include header
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <asm/hardware.h>
-#include <asm/arch/at91_dbgu.h>
-
-	.macro	addruart,rx
-	mrc	p15, 0, \rx, c1, c0
-	tst	\rx, #1				@ MMU enabled?
-	ldreq	\rx, =AT91_BASE_SYS		@ System peripherals (phys address)
-	ldrne	\rx, =AT91_VA_BASE_SYS		@ System peripherals (virt address)
-	.endm
-
-	.macro	senduart,rd,rx
-	strb	\rd, [\rx, #AT91_DBGU_THR]	@ Write to Transmitter Holding Register
-	.endm
-
-	.macro	waituart,rd,rx
-1001:	ldr	\rd, [\rx, #AT91_DBGU_SR]	@ Read Status Register
-	tst	\rd, #AT91_DBGU_TXRDY		@ DBGU_TXRDY = 1 when ready to transmit
-	beq	1001b
-	.endm
-
-	.macro	busyuart,rd,rx
-1001:	ldr	\rd, [\rx, #AT91_DBGU_SR]	@ Read Status Register
-	tst	\rd, #AT91_DBGU_TXEMPTY		@ DBGU_TXEMPTY = 1 when transmission complete
-	beq	1001b
-	.endm
-
diff --git a/include/asm-arm/arch-at91rm9200/entry-macro.S b/include/asm-arm/arch-at91rm9200/entry-macro.S
deleted file mode 100644
index 57248a7..0000000
--- a/include/asm-arm/arch-at91rm9200/entry-macro.S
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * include/asm-arm/arch-at91rm9200/entry-macro.S
- *
- *  Copyright (C) 2003-2005 SAN People
- *
- * Low-level IRQ helper macros for AT91RM9200 platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <asm/hardware.h>
-#include <asm/arch/at91_aic.h>
-
-	.macro	disable_fiq
-	.endm
-
-	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-	ldr	\base, =(AT91_VA_BASE_SYS)		@ base virtual address of SYS peripherals
-	ldr	\irqnr, [\base, #AT91_AIC_IVR]		@ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt)
-	ldr	\irqstat, [\base, #AT91_AIC_ISR]	@ read interrupt source number
-	teq	\irqstat, #0				@ ISR is 0 when no current interrupt, or spurious interrupt
-	streq	\tmp, [\base, #AT91_AIC_EOICR]		@ not going to be handled further, then ACK it now.
-	.endm
-
diff --git a/include/asm-arm/arch-ep93xx/ep93xx-regs.h b/include/asm-arm/arch-ep93xx/ep93xx-regs.h
index 593f562..625c6f0 100644
--- a/include/asm-arm/arch-ep93xx/ep93xx-regs.h
+++ b/include/asm-arm/arch-ep93xx/ep93xx-regs.h
@@ -73,6 +73,11 @@
 
 #define EP93XX_GPIO_BASE		(EP93XX_APB_VIRT_BASE + 0x00040000)
 #define EP93XX_GPIO_REG(x)		(EP93XX_GPIO_BASE + (x))
+#define EP93XX_GPIO_F_INT_TYPE1		EP93XX_GPIO_REG(0x4c)
+#define EP93XX_GPIO_F_INT_TYPE2		EP93XX_GPIO_REG(0x50)
+#define EP93XX_GPIO_F_INT_ACK		EP93XX_GPIO_REG(0x54)
+#define EP93XX_GPIO_F_INT_ENABLE	EP93XX_GPIO_REG(0x58)
+#define EP93XX_GPIO_F_INT_STATUS	EP93XX_GPIO_REG(0x5c)
 #define EP93XX_GPIO_A_INT_TYPE1		EP93XX_GPIO_REG(0x90)
 #define EP93XX_GPIO_A_INT_TYPE2		EP93XX_GPIO_REG(0x94)
 #define EP93XX_GPIO_A_INT_ACK		EP93XX_GPIO_REG(0x98)
diff --git a/include/asm-arm/arch-ep93xx/irqs.h b/include/asm-arm/arch-ep93xx/irqs.h
index ae532e304..2a8c636 100644
--- a/include/asm-arm/arch-ep93xx/irqs.h
+++ b/include/asm-arm/arch-ep93xx/irqs.h
@@ -67,9 +67,13 @@
 #define IRQ_EP93XX_SAI			60
 #define EP93XX_VIC2_VALID_IRQ_MASK	0x1fffffff
 
-#define IRQ_EP93XX_GPIO(x)		(64 + (x))
+/*
+ * Map GPIO A0..A7 to irq 64..71, B0..B7 to 72..79, and
+ * F0..F7 to 80..87.
+ */
+#define IRQ_EP93XX_GPIO(x)		(64 + (((x) + (((x) >> 2) & 8)) & 0x1f))
 
-#define NR_EP93XX_IRQS			IRQ_EP93XX_GPIO(16)
+#define NR_EP93XX_IRQS			(64 + 24)
 
 #define EP93XX_BOARD_IRQ(x)		(NR_EP93XX_IRQS + (x))
 #define EP93XX_BOARD_IRQS		32
diff --git a/include/asm-arm/arch-ep93xx/platform.h b/include/asm-arm/arch-ep93xx/platform.h
index b4a8deb..44eccec 100644
--- a/include/asm-arm/arch-ep93xx/platform.h
+++ b/include/asm-arm/arch-ep93xx/platform.h
@@ -8,7 +8,6 @@
 void ep93xx_init_irq(void);
 void ep93xx_init_time(unsigned long);
 void ep93xx_init_devices(void);
-void ep93xx_clock_init(void);
 extern struct sys_timer ep93xx_timer;
 
 struct ep93xx_eth_data
diff --git a/include/asm-arm/arch-imx/entry-macro.S b/include/asm-arm/arch-imx/entry-macro.S
index 3b9ef69..61bb0bd 100644
--- a/include/asm-arm/arch-imx/entry-macro.S
+++ b/include/asm-arm/arch-imx/entry-macro.S
@@ -13,19 +13,13 @@
 		.endm
 #define AITC_NIVECSR   0x40
 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\irqstat, =IO_ADDRESS(IMX_AITC_BASE)
+		ldr	\base, =IO_ADDRESS(IMX_AITC_BASE)
 		@ Load offset & priority of the highest priority
 		@ interrupt pending.
-		ldr	\irqnr, [\irqstat, #AITC_NIVECSR]
+		ldr	\irqstat, [\base, #AITC_NIVECSR]
 		@ Shift off the priority leaving the offset or
-		@ "interrupt number"
-		mov	\irqnr, \irqnr, lsr #16
- 		ldr	\irqstat, =1	@ dummy compare
-		ldr	\base, =0xFFFF		// invalid interrupt
-		cmp	\irqnr, \base
-		bne	1001f
-		ldr	\irqstat, =0
-1001:
-		tst	\irqstat, #1	@ to make the condition code = TRUE
+		@ "interrupt number", use arithmetic shift to
+		@ transform illegal source (0xffff) as -1
+		mov	\irqnr, \irqstat, asr #16
+		adds	\tmp, \irqnr, #1
 		.endm
-
diff --git a/include/asm-arm/arch-iop32x/io.h b/include/asm-arm/arch-iop32x/io.h
index 12d9ee0..5f570a5 100644
--- a/include/asm-arm/arch-iop32x/io.h
+++ b/include/asm-arm/arch-iop32x/io.h
@@ -13,10 +13,16 @@
 
 #include <asm/hardware.h>
 
-#define IO_SPACE_LIMIT		0xffffffff
+extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
+extern void __iomem *__iop3xx_ioremap(unsigned long cookie, size_t size,
+	unsigned long flags);
+extern void __iop3xx_iounmap(void __iomem *addr);
 
-#define __io(p)			((void __iomem *)(p))
+#define IO_SPACE_LIMIT		0xffffffff
+#define __io(p)		((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
 #define __mem_pci(a)		(a)
 
+#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f)
+#define __arch_iounmap(a)	 __iop3xx_iounmap(a)
 
 #endif
diff --git a/include/asm-arm/arch-iop33x/io.h b/include/asm-arm/arch-iop33x/io.h
index c017402..1bb5071 100644
--- a/include/asm-arm/arch-iop33x/io.h
+++ b/include/asm-arm/arch-iop33x/io.h
@@ -13,9 +13,16 @@
 
 #include <asm/hardware.h>
 
+extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
+extern void __iomem *__iop3xx_ioremap(unsigned long cookie, size_t size,
+	unsigned long flags);
+extern void __iop3xx_iounmap(void __iomem *addr);
+
 #define IO_SPACE_LIMIT		0xffffffff
-#define __io(p)			((void __iomem *)(p))
+#define __io(p)		((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
 #define __mem_pci(a)		(a)
 
+#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f)
+#define __arch_iounmap(a)	 __iop3xx_iounmap(a)
 
 #endif
diff --git a/include/asm-arm/arch-ixp4xx/avila.h b/include/asm-arm/arch-ixp4xx/avila.h
new file mode 100644
index 0000000..0dfea0c
--- /dev/null
+++ b/include/asm-arm/arch-ixp4xx/avila.h
@@ -0,0 +1,39 @@
+/*
+ * include/asm-arm/arch-ixp4xx/avila.h
+ *
+ * Gateworks Avila platform specific definitions
+ *
+ * Author: Michael-Luke Jones <mlj28@cam.ac.uk>
+ *
+ * Based on ixdp425.h
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2004 (c) MontaVista, Software, Inc.
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H__
+#error "Do not include this directly, instead #include <asm/hardware.h>"
+#endif
+
+#define	AVILA_SDA_PIN		7
+#define	AVILA_SCL_PIN		6
+
+/*
+ * AVILA PCI IRQs
+ */
+#define AVILA_PCI_MAX_DEV	4
+#define LOFT_PCI_MAX_DEV    6
+#define AVILA_PCI_IRQ_LINES	4
+
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define AVILA_PCI_INTA_PIN	11
+#define AVILA_PCI_INTB_PIN	10
+#define AVILA_PCI_INTC_PIN	9
+#define AVILA_PCI_INTD_PIN	8
+
+
diff --git a/include/asm-arm/arch-ixp4xx/hardware.h b/include/asm-arm/arch-ixp4xx/hardware.h
index 6acb69c..88fd087 100644
--- a/include/asm-arm/arch-ixp4xx/hardware.h
+++ b/include/asm-arm/arch-ixp4xx/hardware.h
@@ -42,6 +42,7 @@
 
 /* Platform specific details */
 #include "ixdp425.h"
+#include "avila.h"
 #include "coyote.h"
 #include "prpmc1100.h"
 #include "nslu2.h"
diff --git a/include/asm-arm/arch-ixp4xx/irqs.h b/include/asm-arm/arch-ixp4xx/irqs.h
index f24b763..e44a563 100644
--- a/include/asm-arm/arch-ixp4xx/irqs.h
+++ b/include/asm-arm/arch-ixp4xx/irqs.h
@@ -79,6 +79,15 @@
 #define	IRQ_IXDP425_PCI_INTD	IRQ_IXP4XX_GPIO8
 
 /*
+ * Gateworks Avila board IRQs
+ */
+#define	IRQ_AVILA_PCI_INTA	IRQ_IXP4XX_GPIO11
+#define	IRQ_AVILA_PCI_INTB	IRQ_IXP4XX_GPIO10
+#define	IRQ_AVILA_PCI_INTC	IRQ_IXP4XX_GPIO9
+#define	IRQ_AVILA_PCI_INTD	IRQ_IXP4XX_GPIO8
+
+
+/*
  * PrPMC1100 Board IRQs
  */
 #define	IRQ_PRPMC1100_PCI_INTA	IRQ_IXP4XX_GPIO11
diff --git a/include/asm-arm/arch-ixp4xx/udc.h b/include/asm-arm/arch-ixp4xx/udc.h
index dbdec36..79b850a 100644
--- a/include/asm-arm/arch-ixp4xx/udc.h
+++ b/include/asm-arm/arch-ixp4xx/udc.h
@@ -6,3 +6,25 @@
 
 extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info);
 
+static inline int udc_gpio_to_irq(unsigned gpio)
+{
+	return 0;
+}
+
+static inline void udc_gpio_init_vbus(unsigned gpio)
+{
+}
+
+static inline void udc_gpio_init_pullup(unsigned gpio)
+{
+}
+
+static inline int udc_gpio_get(unsigned gpio)
+{
+	return 0;
+}
+
+static inline void udc_gpio_set(unsigned gpio, int is_on)
+{
+}
+
diff --git a/include/asm-arm/arch-ns9xxx/board.h b/include/asm-arm/arch-ns9xxx/board.h
new file mode 100644
index 0000000..91dc8fb
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/board.h
@@ -0,0 +1,18 @@
+/*
+ * include/asm-arm/arch-ns9xxx/board.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_BOARD_H
+#define __ASM_ARCH_BOARD_H
+
+#include <asm/mach-types.h>
+
+#define board_is_a9m9750dev()	(machine_is_cc9p9360dev())
+
+#endif /* ifndef __ASM_ARCH_BOARD_H */
diff --git a/include/asm-arm/arch-ns9xxx/clock.h b/include/asm-arm/arch-ns9xxx/clock.h
new file mode 100644
index 0000000..4371a48
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/clock.h
@@ -0,0 +1,37 @@
+/*
+ * include/asm-arm/arch-ns9xxx/clock.h
+ *
+ * Copyright (C) 2007 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_CLOCK_H
+#define __ASM_ARCH_CLOCK_H
+
+static inline u32 ns9xxx_systemclock(void)
+{
+	/*
+	 * This should be a multiple of HZ * TIMERCLOCKSELECT (in time.c)
+	 */
+	return 353894400;
+}
+
+static inline const u32 ns9xxx_cpuclock(void)
+{
+	return ns9xxx_systemclock() / 2;
+}
+
+static inline const u32 ns9xxx_ahbclock(void)
+{
+	return ns9xxx_systemclock() / 4;
+}
+
+static inline const u32 ns9xxx_bbusclock(void)
+{
+	return ns9xxx_systemclock() / 8;
+}
+
+#endif /* ifndef __ASM_ARCH_CLOCK_H */
diff --git a/include/asm-arm/arch-ns9xxx/debug-macro.S b/include/asm-arm/arch-ns9xxx/debug-macro.S
new file mode 100644
index 0000000..b21b93e
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/debug-macro.S
@@ -0,0 +1,22 @@
+/*
+ * include/asm-arm/arch-ns9xxx/debug-macro.S
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <asm/hardware.h>
+
+#include <asm/arch-ns9xxx/regs-board-a9m9750dev.h>
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1
+		ldreq	\rx, =NS9XXX_CSxSTAT_PHYS(0)
+		ldrne	\rx, =io_p2v(NS9XXX_CSxSTAT_PHYS(0))
+		.endm
+
+#define UART_SHIFT	2
+#include <asm/hardware/debug-8250.S>
diff --git a/include/asm-arm/arch-ns9xxx/dma.h b/include/asm-arm/arch-ns9xxx/dma.h
new file mode 100644
index 0000000..a67cbbe
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/dma.h
@@ -0,0 +1,14 @@
+/*
+ * include/asm-arm/arch-ns9xxx/dma.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#endif /* ifndef __ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-ns9xxx/entry-macro.S b/include/asm-arm/arch-ns9xxx/entry-macro.S
new file mode 100644
index 0000000..467a198
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/entry-macro.S
@@ -0,0 +1,22 @@
+/*
+ * include/asm-arm/arch-ns9xxx/entry-macro.S
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <asm/hardware.h>
+#include <asm/arch-ns9xxx/regs-sys.h>
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\base, =SYS_ISRADDR
+		ldr	\irqstat, [\base, #(SYS_ISA - SYS_ISRADDR)]
+		cmp	\irqstat, #0
+		ldrne	\irqnr, [\base]
+		.endm
+
+		.macro	disable_fiq
+		.endm
diff --git a/include/asm-arm/arch-ns9xxx/hardware.h b/include/asm-arm/arch-ns9xxx/hardware.h
new file mode 100644
index 0000000..6819da7
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/hardware.h
@@ -0,0 +1,67 @@
+/*
+ * include/asm-arm/arch-ns9xxx/hardware.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/memory.h>
+
+/*
+ * NetSilicon NS9xxx internal mapping:
+ *
+ * physical                <--> virtual
+ * 0x90000000 - 0x906fffff <--> 0xf9000000 - 0xf96fffff
+ * 0xa0100000 - 0xa0afffff <--> 0xfa100000 - 0xfaafffff
+ */
+#define io_p2v(x)	(0xf0000000 \
+			 + (((x) & 0xf0000000) >> 4) \
+			 + ((x) & 0x00ffffff))
+
+#define io_v2p(x)	((((x) & 0x0f000000) << 4) \
+			 + ((x) & 0x00ffffff))
+
+#define __REGBIT(bit)		((u32)1 << (bit))
+#define __REGBITS(hbit, lbit)	((((u32)1 << ((hbit) - (lbit) + 1)) - 1) << (lbit))
+#define __REGVAL(mask, value)	(((value) * ((mask) & (-(mask))) & (mask)))
+
+#ifndef __ASSEMBLY__
+
+#  define __REG(x)	(*((volatile u32 *)io_p2v((x))))
+#  define __REG2(x, y)	(*((volatile u32 *)io_p2v((x)) + (y)))
+
+#  define __REGB(x)	(*((volatile u8 *)io_p2v((x))))
+#  define __REGB2(x)	(*((volatile u8 *)io_p2v((x)) + (y)))
+
+#  define REGSET(var, reg, field, value)				\
+	((var) = (((var)						\
+		   & ~(reg ## _ ## field & 				\
+		       ~ reg ## _ ## field ## _ ## value))		\
+		  | (reg ## _ ## field ## _ ## value)))
+
+#  define REGSETIM(var, reg, field, value)				\
+	((var) = (((var)						\
+		   & ~(reg ## _ ## field & 				\
+		       ~(__REGVAL(reg ## _ ## field, value))))		\
+		  | (__REGVAL(reg ## _ ## field, value))))
+
+#  define REGGET(reg, field)						\
+	((reg & (reg ## _ ## field)) / (field & (-field)))
+
+#else
+
+#  define __REG(x)	io_p2v(x)
+#  define __REG2(x, y)	io_p2v((x) + (y))
+
+#  define __REGB(x)	__REG((x))
+#  define __REGB2(x, y)	__REG2((x), (y))
+
+#endif
+
+#endif /* ifndef __ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-ns9xxx/io.h b/include/asm-arm/arch-ns9xxx/io.h
new file mode 100644
index 0000000..6f82d28
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/io.h
@@ -0,0 +1,20 @@
+/*
+ * include/asm-arm/arch-ns9xxx/io.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT  0xffffffff /* XXX */
+
+#define __io(a)         ((void __iomem *)(a))
+#define __mem_pci(a)    (a)
+#define __mem_isa(a)    (IO_BASE + (a))
+
+#endif /* ifndef __ASM_ARCH_IO_H */
diff --git a/include/asm-arm/arch-ns9xxx/irqs.h b/include/asm-arm/arch-ns9xxx/irqs.h
new file mode 100644
index 0000000..25d8d28
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/irqs.h
@@ -0,0 +1,85 @@
+/*
+ * include/asm-arm/arch-ns9xxx/irqs.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define IRQ_WATCHDOG	0
+#define IRQ_AHBBUSERR	1
+#define IRQ_BBUSAGG	2
+/* irq 3 is reserved for NS9360 */
+#define IRQ_ETHRX	4
+#define IRQ_ETHTX	5
+#define IRQ_ETHPHY	6
+#define IRQ_LCD		7
+#define IRQ_SERBRX	8
+#define IRQ_SERBTX	9
+#define IRQ_SERARX	10
+#define IRQ_SERATX	11
+#define IRQ_SERCRX	12
+#define IRQ_SERCTX	13
+#define IRQ_I2C		14
+#define IRQ_BBUSDMA	15
+#define IRQ_TIMER0	16
+#define IRQ_TIMER1	17
+#define IRQ_TIMER2	18
+#define IRQ_TIMER3	19
+#define IRQ_TIMER4	20
+#define IRQ_TIMER5	21
+#define IRQ_TIMER6	22
+#define IRQ_TIMER7	23
+#define IRQ_RTC		24
+#define IRQ_USBHOST	25
+#define IRQ_USBDEVICE	26
+#define IRQ_IEEE1284	27
+#define IRQ_EXT0	28
+#define IRQ_EXT1	29
+#define IRQ_EXT2	30
+#define IRQ_EXT3	31
+
+#define BBUS_IRQ(irq)	(32 + irq)
+
+#define IRQ_BBUS_DMA		BBUS_IRQ(0)
+#define IRQ_BBUS_SERBRX		BBUS_IRQ(2)
+#define IRQ_BBUS_SERBTX		BBUS_IRQ(3)
+#define IRQ_BBUS_SERARX		BBUS_IRQ(4)
+#define IRQ_BBUS_SERATX		BBUS_IRQ(5)
+#define IRQ_BBUS_SERCRX		BBUS_IRQ(6)
+#define IRQ_BBUS_SERCTX		BBUS_IRQ(7)
+#define IRQ_BBUS_SERDRX		BBUS_IRQ(8)
+#define IRQ_BBUS_SERDTX		BBUS_IRQ(9)
+#define IRQ_BBUS_I2C		BBUS_IRQ(10)
+#define IRQ_BBUS_1284		BBUS_IRQ(11)
+#define IRQ_BBUS_UTIL		BBUS_IRQ(12)
+#define IRQ_BBUS_RTC		BBUS_IRQ(13)
+#define IRQ_BBUS_USBHST		BBUS_IRQ(14)
+#define IRQ_BBUS_USBDEV		BBUS_IRQ(15)
+#define IRQ_BBUS_AHBDMA1	BBUS_IRQ(24)
+#define IRQ_BBUS_AHBDMA2	BBUS_IRQ(25)
+
+/*
+ * these Interrupts are specific for the a9m9750dev board.
+ * They are generated by an FPGA that interrupts the CPU on
+ * IRQ_EXT2
+ */
+#define FPGA_IRQ(irq)	(64 + irq)
+
+#define IRQ_FPGA_UARTA		FPGA_IRQ(0)
+#define IRQ_FPGA_UARTB		FPGA_IRQ(1)
+#define IRQ_FPGA_UARTC		FPGA_IRQ(2)
+#define IRQ_FPGA_UARTD		FPGA_IRQ(3)
+#define IRQ_FPGA_TOUCH		FPGA_IRQ(4)
+#define IRQ_FPGA_CF		FPGA_IRQ(5)
+#define IRQ_FPGA_CAN0		FPGA_IRQ(6)
+#define IRQ_FPGA_CAN1		FPGA_IRQ(7)
+
+#define NR_IRQS	72
+
+#endif /* __ASM_ARCH_IRQS_H */
diff --git a/include/asm-arm/arch-ns9xxx/memory.h b/include/asm-arm/arch-ns9xxx/memory.h
new file mode 100644
index 0000000..ce1343e
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/memory.h
@@ -0,0 +1,27 @@
+/*
+ * include/asm-arm/arch-ns9xxx/memory.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+*/
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/* x in [0..3] */
+#define NS9XXX_CSxSTAT_PHYS(x)	UL(((x) + 4) << 28)
+
+#define NS9XXX_CS0STAT_LENGTH	UL(0x1000)
+#define NS9XXX_CS1STAT_LENGTH	UL(0x1000)
+#define NS9XXX_CS2STAT_LENGTH	UL(0x1000)
+#define NS9XXX_CS3STAT_LENGTH	UL(0x1000)
+
+#define PHYS_OFFSET	UL(0x00000000)
+
+#define __virt_to_bus(x) __virt_to_phys(x)
+#define __bus_to_virt(x) __phys_to_virt(x)
+
+#endif
diff --git a/include/asm-arm/arch-ns9xxx/processor.h b/include/asm-arm/arch-ns9xxx/processor.h
new file mode 100644
index 0000000..716c106
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/processor.h
@@ -0,0 +1,18 @@
+/*
+ * include/asm-arm/arch-ns9xxx/processor.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+#include <asm/mach-types.h>
+
+#define processor_is_ns9360()	(machine_is_cc9p9360dev())
+
+#endif /* ifndef __ASM_ARCH_PROCESSOR_H */
diff --git a/include/asm-arm/arch-ns9xxx/regs-bbu.h b/include/asm-arm/arch-ns9xxx/regs-bbu.h
new file mode 100644
index 0000000..e262695
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/regs-bbu.h
@@ -0,0 +1,21 @@
+/*
+ * include/asm-arm/arch-ns9xxx/regs-bbu.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_REGSBBU_H
+#define __ASM_ARCH_REGSBBU_H
+
+#include <asm/hardware.h>
+
+/* BBus Utility */
+
+/* GPIO Configuration Register */
+#define BBU_GC(x)	__REG2(0x9060000c, (x))
+
+#endif /* ifndef __ASM_ARCH_REGSBBU_H */
diff --git a/include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h b/include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h
new file mode 100644
index 0000000..c3dc532
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h
@@ -0,0 +1,24 @@
+/*
+ * include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_REGSBOARDA9M9750_H
+#define __ASM_ARCH_REGSBOARDA9M9750_H
+
+#include <asm/hardware.h>
+
+#define FPGA_UARTA_BASE	io_p2v(NS9XXX_CSxSTAT_PHYS(0))
+#define FPGA_UARTB_BASE	io_p2v(NS9XXX_CSxSTAT_PHYS(0) + 0x08)
+#define FPGA_UARTC_BASE	io_p2v(NS9XXX_CSxSTAT_PHYS(0) + 0x10)
+#define FPGA_UARTD_BASE	io_p2v(NS9XXX_CSxSTAT_PHYS(0) + 0x18)
+
+#define FPGA_IER	__REGB(NS9XXX_CSxSTAT_PHYS(0) + 0x50)
+#define FPGA_ISR	__REGB(NS9XXX_CSxSTAT_PHYS(0) + 0x60)
+
+#endif /* ifndef __ASM_ARCH_REGSBOARDA9M9750_H */
diff --git a/include/asm-arm/arch-ns9xxx/regs-mem.h b/include/asm-arm/arch-ns9xxx/regs-mem.h
new file mode 100644
index 0000000..8ed8448
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/regs-mem.h
@@ -0,0 +1,135 @@
+/*
+ * include/asm-arm/arch-ns9xxx/regs-mem.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_REGSMEM_H
+#define __ASM_ARCH_REGSMEM_H
+
+#include <asm/hardware.h>
+
+/* Memory Module */
+
+/* Control register */
+#define MEM_CTRL	__REG(0xa0700000)
+
+/* Status register */
+#define MEM_STAT	__REG(0xa0700004)
+
+/* Configuration register */
+#define MEM_CONF	__REG(0xa0700008)
+
+/* Dynamic Memory Control register */
+#define MEM_DMCTRL	__REG(0xa0700020)
+
+/* Dynamic Memory Refresh Timer */
+#define MEM_DMRT	__REG(0xa0700024)
+
+/* Dynamic Memory Read Configuration register */
+#define MEM_DMRC	__REG(0xa0700028)
+
+/* Dynamic Memory Precharge Command Period (tRP) */
+#define MEM_DMPCP	__REG(0xa0700030)
+
+/* Dynamic Memory Active to Precharge Command Period (tRAS) */
+#define MEM_DMAPCP	__REG(0xa0700034)
+
+/* Dynamic Memory Self-Refresh Exit Time (tSREX) */
+#define MEM_DMSRET	__REG(0xa0700038)
+
+/* Dynamic Memory Last Data Out to Active Time (tAPR) */
+#define MEM_DMLDOAT	__REG(0xa070003c)
+
+/* Dynamic Memory Data-in to Active Command Time (tDAL or TAPW) */
+#define MEM_DMDIACT	__REG(0xa0700040)
+
+/* Dynamic Memory Write Recovery Time (tWR, tDPL, tRWL, tRDL) */
+#define MEM_DMWRT	__REG(0xa0700044)
+
+/* Dynamic Memory Active to Active Command Period (tRC) */
+#define MEM_DMAACP	__REG(0xa0700048)
+
+/* Dynamic Memory Auto Refresh Period, and Auto Refresh to Active Command Period (tRFC) */
+#define MEM_DMARP	__REG(0xa070004c)
+
+/* Dynamic Memory Exit Self-Refresh to Active Command (tXSR) */
+#define MEM_DMESRAC	__REG(0xa0700050)
+
+/* Dynamic Memory Active Bank A to Active B Time (tRRD) */
+#define MEM_DMABAABT	__REG(0xa0700054)
+
+/* Dynamic Memory Load Mode register to Active Command Time (tMRD) */
+#define MEM_DMLMACT	__REG(0xa0700058)
+
+/* Static Memory Extended Wait */
+#define MEM_SMEW	__REG(0xa0700080)
+
+/* Dynamic Memory Configuration Register x */
+#define MEM_DMCONF(x) 	__REG2(0xa0700100, (x) << 3)
+
+/* Dynamic Memory RAS and CAS Delay x */
+#define MEM_DMRCD(x)	__REG2(0xa0700104, (x) << 3)
+
+/* Static Memory Configuration Register x */
+#define MEM_SMC(x)	__REG2(0xa0700200, (x) << 3)
+
+/* Static Memory Configuration Register x: Write protect */
+#define MEM_SMC_WSMC		__REGBIT(20)
+#define MEM_SMC_WSMC_OFF		__REGVAL(MEM_SMC_WSMC, 0)
+#define MEM_SMC_WSMC_ON			__REGVAL(MEM_SMC_WSMC, 1)
+
+/* Static Memory Configuration Register x: Buffer enable */
+#define MEM_SMC_BSMC		__REGBIT(19)
+#define MEM_SMC_BSMC_OFF		__REGVAL(MEM_SMC_BSMC, 0)
+#define MEM_SMC_BSMC_ON			__REGVAL(MEM_SMC_BSMC, 1)
+
+/* Static Memory Configuration Register x: Extended Wait */
+#define MEM_SMC_EW		__REGBIT(8)
+#define MEM_SMC_EW_OFF			__REGVAL(MEM_SMC_EW, 0)
+#define MEM_SMC_EW_ON			__REGVAL(MEM_SMC_EW, 1)
+
+/* Static Memory Configuration Register x: Byte lane state */
+#define MEM_SMC_PB		__REGBIT(7)
+#define MEM_SMC_PB_0			__REGVAL(MEM_SMC_PB, 0)
+#define MEM_SMC_PB_1			__REGVAL(MEM_SMC_PB, 1)
+
+/* Static Memory Configuration Register x: Chip select polarity */
+#define MEM_SMC_PC		__REGBIT(6)
+#define MEM_SMC_PC_AL			__REGVAL(MEM_SMC_PC, 0)
+#define MEM_SMC_PC_AH			__REGVAL(MEM_SMC_PC, 1)
+
+/* static memory configuration register x: page mode*/
+#define MEM_SMC_PM		__REGBIT(3)
+#define MEM_SMC_PM_DIS			__REGVAL(MEM_SMC_PM, 0)
+#define MEM_SMC_PM_ASYNC		__REGVAL(MEM_SMC_PM, 1)
+
+/* static memory configuration register x: Memory width */
+#define MEM_SMC_MW		__REGBITS(1, 0)
+#define MEM_SMC_MW_8			__REGVAL(MEM_SMC_MW, 0)
+#define MEM_SMC_MW_16			__REGVAL(MEM_SMC_MW, 1)
+#define MEM_SMC_MW_32			__REGVAL(MEM_SMC_MW, 2)
+
+/* Static Memory Write Enable Delay x */
+#define MEM_SMWED(x)	__REG2(0xa0700204, (x) << 3)
+
+/* Static Memory Output Enable Delay x */
+#define MEM_SMOED(x)	__REG2(0xa0700208, (x) << 3)
+
+/* Static Memory Read Delay x */
+#define MEM_SMRD(x)	__REG2(0xa070020c, (x) << 3)
+
+/* Static Memory Page Mode Read Delay 0 */
+#define MEM_SMPMRD(x)	__REG2(0xa0700210, (x) << 3)
+
+/* Static Memory Write Delay */
+#define MEM_SMWD(x)	__REG2(0xa0700214, (x) << 3)
+
+/* Static Memory Turn Round Delay x */
+#define MEM_SWT(x)	__REG2(0xa0700218, (x) << 3)
+
+#endif /* ifndef __ASM_ARCH_REGSMEM_H */
diff --git a/include/asm-arm/arch-ns9xxx/regs-sys.h b/include/asm-arm/arch-ns9xxx/regs-sys.h
new file mode 100644
index 0000000..8162a50
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/regs-sys.h
@@ -0,0 +1,157 @@
+/*
+ * include/asm-arm/arch-ns9xxx/regs-sys.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_REGSSYS_H
+#define __ASM_ARCH_REGSSYS_H
+
+#include <asm/hardware.h>
+
+/* System Control Module */
+
+/* AHB Arbiter Gen Configuration */
+#define SYS_AHBAGENCONF	__REG(0xa0900000)
+
+/* BRC */
+#define SYS_BRC(x)	__REG2(0xa0900004, (x))
+
+/* Timer x Reload Count register */
+#define SYS_TRC(x)	__REG2(0xa0900044, (x))
+
+/* Timer x Read register */
+#define SYS_TR(x)	__REG2(0xa0900084, (x))
+
+/* Interrupt Vector Address Register Level x */
+#define SYS_IVA(x)	__REG2(0xa09000c4, (x))
+
+/* Interrupt Configuration registers */
+#define SYS_IC(x)	__REG2(0xa0900144, (x))
+
+/* ISRADDR */
+#define SYS_ISRADDR	__REG(0xa0900164)
+
+/* Interrupt Status Active */
+#define SYS_ISA		__REG(0xa0900168)
+
+/* Interrupt Status Raw */
+#define SYS_ISR		__REG(0xa090016c)
+
+/* Timer Interrupt Status register */
+#define SYS_TIS		__REG(0xa0900170)
+
+/* PLL Configuration register */
+#define SYS_PLL		__REG(0xa0900188)
+
+/* PLL Configuration register: PLL SW change */
+#define SYS_PLL_SWC		__REGBIT(15)
+#define SYS_PLL_SWC_NO			__REGVAL(SYS_PLL_SWC, 0)
+#define SYS_PLL_SWC_YES			__REGVAL(SYS_PLL_SWC, 1)
+
+/* Timer x Control register */
+#define SYS_TC(x)	__REG2(0xa0900190, (x))
+
+/* Timer x Control register: Timer enable */
+#define SYS_TCx_TEN		__REGBIT(15)
+#define SYS_TCx_TEN_DIS			__REGVAL(SYS_TCx_TEN, 1)
+#define SYS_TCx_TEN_EN			__REGVAL(SYS_TCx_TEN, 1)
+
+/* Timer x Control register: CPU debug mode */
+#define SYS_TCx_TDBG		__REGBIT(10)
+#define SYS_TCx_TDBG_CONT		__REGVAL(SYS_TCx_TDBG, 0)
+#define SYS_TCx_TDBG_STOP		__REGVAL(SYS_TCx_TDBG, 1)
+
+/* Timer x Control register: Interrupt clear */
+#define SYS_TCx_INTC		__REGBIT(9)
+#define SYS_TCx_INTC_UNSET		__REGVAL(SYS_TCx_INTC, 0)
+#define SYS_TCx_INTC_SET		__REGVAL(SYS_TCx_INTC, 1)
+
+/* Timer x Control register: Timer clock select */
+#define SYS_TCx_TLCS		__REGBITS(8, 6)
+#define SYS_TCx_TLCS_CPU		__REGVAL(SYS_TCx_TLCS, 0)	/* CPU clock */
+#define SYS_TCx_TLCS_DIV2		__REGVAL(SYS_TCx_TLCS, 1)	/* CPU clock / 2 */
+#define SYS_TCx_TLCS_DIV4		__REGVAL(SYS_TCx_TLCS, 2)	/* CPU clock / 4 */
+#define SYS_TCx_TLCS_DIV8		__REGVAL(SYS_TCx_TLCS, 3)	/* CPU clock / 8 */
+#define SYS_TCx_TLCS_DIV16		__REGVAL(SYS_TCx_TLCS, 4)	/* CPU clock / 16 */
+#define SYS_TCx_TLCS_DIV32		__REGVAL(SYS_TCx_TLCS, 5)	/* CPU clock / 32 */
+#define SYS_TCx_TLCS_DIV64		__REGVAL(SYS_TCx_TLCS, 6)	/* CPU clock / 64 */
+#define SYS_TCx_TLCS_EXT		__REGVAL(SYS_TCx_TLCS, 7)
+
+/* Timer x Control register: Timer mode */
+#define SYS_TCx_TM		__REGBITS(5, 4)
+#define SYS_TCx_TM_IEE			__REGVAL(SYS_TCx_TM, 0)		/* Internal timer or external event */
+#define SYS_TCx_TM_ELL			__REGVAL(SYS_TCx_TM, 1)		/* External low-level, gated timer */
+#define SYS_TCx_TM_EHL			__REGVAL(SYS_TCx_TM, 2)		/* External high-level, gated timer */
+#define SYS_TCx_TM_CONCAT		__REGVAL(SYS_TCx_TM, 3)		/* Concatenate the lower timer. */
+
+/* Timer x Control register: Interrupt select */
+#define SYS_TCx_INTS		__REGBIT(3)
+#define SYS_TCx_INTS_DIS		__REGVAL(SYS_TCx_INTS, 0)
+#define SYS_TCx_INTS_EN			__REGVAL(SYS_TCx_INTS, 1)
+
+/* Timer x Control register: Up/down select */
+#define SYS_TCx_UDS		__REGBIT(2)
+#define SYS_TCx_UDS_UP			__REGVAL(SYS_TCx_UDS, 0)
+#define SYS_TCx_UDS_DOWN		__REGVAL(SYS_TCx_UDS, 1)
+
+/* Timer x Control register: 32- or 16-bit timer */
+#define SYS_TCx_TSZ		__REGBIT(1)
+#define SYS_TCx_TSZ_16			__REGVAL(SYS_TCx_TSZ, 0)
+#define SYS_TCx_TSZ_32			__REGVAL(SYS_TCx_TSZ, 1)
+
+/* Timer x Control register: Reload enable */
+#define SYS_TCx_REN		__REGBIT(0)
+#define SYS_TCx_REN_DIS			__REGVAL(SYS_TCx_REN, 0)
+#define SYS_TCx_REN_EN			__REGVAL(SYS_TCx_REN, 1)
+
+/* System Memory Chip Select x Dynamic Memory Base */
+#define SYS_SMCSDMB(x)	__REG2(0xa09001d0, (x) << 1)
+
+/* System Memory Chip Select x Dynamic Memory Mask */
+#define SYS_SMCSDMM(x)	__REG2(0xa09001d4, (x) << 1)
+
+/* System Memory Chip Select x Static Memory Base */
+#define SYS_SMCSSMB(x)	__REG2(0xa09001f0, (x) << 1)
+
+/* System Memory Chip Select x Static Memory Base: Chip select x base */
+#define SYS_SMCSSMB_CSxB	__REGBITS(31, 12)
+
+/* System Memory Chip Select x Static Memory Mask */
+#define SYS_SMCSSMM(x)	__REG2(0xa09001f4, (x) << 1)
+
+/* System Memory Chip Select x Static Memory Mask: Chip select x mask */
+#define SYS_SMCSSMM_CSxM	__REGBITS(31, 12)
+
+/* System Memory Chip Select x Static Memory Mask: Chip select x enable */
+#define SYS_SMCSSMM_CSEx	__REGBIT(0)
+#define SYS_SMCSSMM_CSEx_DIS		__REGVAL(SYS_SMCSSMM_CSEx, 0)
+#define SYS_SMCSSMM_CSEx_EN		__REGVAL(SYS_SMCSSMM_CSEx, 1)
+
+/* General purpose, user-defined ID register */
+#define SYS_GENID	__REG(0xa0900210)
+
+/* External Interrupt x Control register */
+#define SYS_EIC(x)	__REG2(0xa0900214, (x))
+
+/* External Interrupt x Control register: Status */
+#define SYS_EIC_STS		__REGBIT(3)
+
+/* External Interrupt x Control register: Clear */
+#define SYS_EIC_CLR		__REGBIT(2)
+
+/* External Interrupt x Control register: Polarity */
+#define SYS_EIC_PLTY		__REGBIT(1)
+#define SYS_EIC_PLTY_AH			__REGVAL(SYS_EIC_PLTY, 0)
+#define SYS_EIC_PLTY_AL			__REGVAL(SYS_EIC_PLTY, 1)
+
+/* External Interrupt x Control register: Level edge */
+#define SYS_EIC_LVEDG		__REGBIT(0)
+#define SYS_EIC_LVEDG_LEVEL		__REGVAL(SYS_EIC_LVEDG, 0)
+#define SYS_EIC_LVEDG_EDGE		__REGVAL(SYS_EIC_LVEDG, 1)
+
+#endif /* ifndef __ASM_ARCH_REGSSYS_H */
diff --git a/include/asm-arm/arch-ns9xxx/system.h b/include/asm-arm/arch-ns9xxx/system.h
new file mode 100644
index 0000000..e3cd4d3
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/system.h
@@ -0,0 +1,34 @@
+/*
+ * include/asm-arm/arch-ns9xxx/system.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/proc-fns.h>
+#include <asm/arch-ns9xxx/regs-sys.h>
+#include <asm/mach-types.h>
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+	u32 reg;
+
+	reg = SYS_PLL >> 16;
+	REGSET(reg, SYS_PLL, SWC, YES);
+	SYS_PLL = reg;
+
+	BUG();
+}
+
+#endif /* ifndef __ASM_ARCH_SYSTEM_H */
diff --git a/include/asm-arm/arch-ns9xxx/timex.h b/include/asm-arm/arch-ns9xxx/timex.h
new file mode 100644
index 0000000..f776cbd
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/timex.h
@@ -0,0 +1,20 @@
+/*
+ * include/asm-arm/arch-ns9xxx/timex.h
+ *
+ * Copyright (C) 2005-2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/*
+ * value for CLOCK_TICK_RATE stolen from include/asm-arm/arch-s3c2410/timex.h.
+ * See there for an explanation.
+ */
+#define CLOCK_TICK_RATE         12000000
+
+#endif /* ifndef __ASM_ARCH_TIMEX_H */
diff --git a/include/asm-arm/arch-ns9xxx/uncompress.h b/include/asm-arm/arch-ns9xxx/uncompress.h
new file mode 100644
index 0000000..961ca7d
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/uncompress.h
@@ -0,0 +1,35 @@
+/*
+ * include/asm-arm/arch-ns9xxx/uncompress.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+static void putc(char c)
+{
+	volatile u8 *base = (volatile u8 *)0x40000000;
+	int t = 0x10000;
+
+	do {
+		if (base[5] & 0x20) {
+			base[0] = c;
+			break;
+		}
+	} while (--t);
+}
+
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+static void flush(void)
+{
+	/* nothing */
+}
+
+#endif /* ifndef __ASM_ARCH_UNCOMPRESS_H */
diff --git a/include/asm-arm/arch-ns9xxx/vmalloc.h b/include/asm-arm/arch-ns9xxx/vmalloc.h
new file mode 100644
index 0000000..2f3cb6f
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/vmalloc.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-arm/arch-ns9xxx/vmalloc.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END     (0xf0000000)
+
+#endif /* ifndef __ASM_ARCH_VMALLOC_H */
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index e24f6b6..aec835b 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -463,9 +463,6 @@
  * Serial Audio Controller
  */
 
-/* FIXME: This clash with SA1111 defines */
-#ifndef _ASM_ARCH_SA1111
-
 #define SACR0		__REG(0x40400000)  /* Global Control Register */
 #define SACR1		__REG(0x40400004)  /* Serial Audio I 2 S/MSB-Justified Control Register */
 #define SASR0		__REG(0x4040000C)  /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
@@ -474,8 +471,8 @@
 #define SADIV		__REG(0x40400060)  /* Audio Clock Divider Register. */
 #define SADR		__REG(0x40400080)  /* Serial Audio Data Register (TX and RX FIFO access Register). */
 
-#define SACR0_RFTH(x)	(x << 12)	/* Rx FIFO Interrupt or DMA Trigger Threshold */
-#define SACR0_TFTH(x)	(x << 8)	/* Tx FIFO Interrupt or DMA Trigger Threshold */
+#define SACR0_RFTH(x)	((x) << 12)	/* Rx FIFO Interrupt or DMA Trigger Threshold */
+#define SACR0_TFTH(x)	((x) << 8)	/* Tx FIFO Interrupt or DMA Trigger Threshold */
 #define SACR0_STRF	(1 << 5)	/* FIFO Select for EFWR Special Function */
 #define SACR0_EFWR	(1 << 4)	/* Enable EFWR Function  */
 #define SACR0_RST	(1 << 3)	/* FIFO, i2s Register Reset */
@@ -503,8 +500,6 @@
 #define SAIMR_RFS	(1 << 4)	/* Enable Rx FIFO Service Interrupt */
 #define SAIMR_TFS	(1 << 3)	/* Enable Tx FIFO Service Interrupt */
 
-#endif
-
 /*
  * AC97 Controller registers
  */
@@ -1682,15 +1677,18 @@
 #define SSSR_PINT		(1 << 18)	/* Peripheral Trailing Byte Interrupt */
 
 #define SSPSP_FSRT		(1 << 25)	/* Frame Sync Relative Timing */
-#define SSPSP_DMYSTOP(x)	(x << 23)	/* Dummy Stop */
-#define SSPSP_SFRMWDTH(x)	(x << 16)	/* Serial Frame Width */
-#define SSPSP_SFRMDLY(x)	(x << 9)	/* Serial Frame Delay */
-#define SSPSP_DMYSTRT(x)	(x << 7)	/* Dummy Start */
-#define SSPSP_STRTDLY(x)	(x << 4)	/* Start Delay */
+#define SSPSP_DMYSTOP(x)	((x) << 23)	/* Dummy Stop */
+#define SSPSP_SFRMWDTH(x)	((x) << 16)	/* Serial Frame Width */
+#define SSPSP_SFRMDLY(x)	((x) << 9)	/* Serial Frame Delay */
+#define SSPSP_DMYSTRT(x)	((x) << 7)	/* Dummy Start */
+#define SSPSP_STRTDLY(x)	((x) << 4)	/* Start Delay */
 #define SSPSP_ETDS			(1 << 3)	/* End of Transfer data State */
 #define SSPSP_SFRMP			(1 << 2)	/* Serial Frame Polarity */
-#define SSPSP_SCMODE(x)		(x << 0)	/* Serial Bit Rate Clock Mode */
+#define SSPSP_SCMODE(x)		((x) << 0)	/* Serial Bit Rate Clock Mode */
 
+#define SSACD_SCDB		(1 << 3)	/* SSPSYSCLK Divider Bypass */
+#define SSACD_ACPS(x)		((x) << 4)	/* Audio clock PLL select */
+#define SSACD_ACDS(x)		((x) << 0)	/* Audio clock divider select */
 
 #define SSCR0_P1	__REG(0x41000000)  /* SSP Port 1 Control Register 0 */
 #define SSCR1_P1	__REG(0x41000004)  /* SSP Port 1 Control Register 1 */
diff --git a/include/asm-arm/arch-pxa/udc.h b/include/asm-arm/arch-pxa/udc.h
index 646480d..8bc6f9c 100644
--- a/include/asm-arm/arch-pxa/udc.h
+++ b/include/asm-arm/arch-pxa/udc.h
@@ -9,3 +9,33 @@
 
 extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info);
 
+static inline int udc_gpio_to_irq(unsigned gpio)
+{
+	return IRQ_GPIO(gpio & GPIO_MD_MASK_NR);
+}
+
+static inline void udc_gpio_init_vbus(unsigned gpio)
+{
+	pxa_gpio_mode((gpio & GPIO_MD_MASK_NR) | GPIO_IN);
+}
+
+static inline void udc_gpio_init_pullup(unsigned gpio)
+{
+	pxa_gpio_mode((gpio & GPIO_MD_MASK_NR) | GPIO_OUT | GPIO_DFLT_LOW);
+}
+
+static inline int udc_gpio_get(unsigned gpio)
+{
+	return (GPLR(gpio) & GPIO_bit(gpio)) != 0;
+}
+
+static inline void udc_gpio_set(unsigned gpio, int is_on)
+{
+	int mask = GPIO_bit(gpio);
+
+	if (is_on)
+		GPSR(gpio) = mask;
+	else
+		GPCR(gpio) = mask;
+}
+
diff --git a/include/asm-arm/arch-realview/hardware.h b/include/asm-arm/arch-realview/hardware.h
index 9ca76dc..aa78fe0 100644
--- a/include/asm-arm/arch-realview/hardware.h
+++ b/include/asm-arm/arch-realview/hardware.h
@@ -26,7 +26,7 @@
 #include <asm/arch/platform.h>
 
 /* macro to get at IO space when running virtually */
-#define IO_ADDRESS(x)		(((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
+#define IO_ADDRESS(x)		((((x) & 0x0effffff) | (((x) >> 4) & 0x0f000000)) + 0xf0000000)
 #define __io_address(n)		__io(IO_ADDRESS(n))
 
 #endif
diff --git a/include/asm-arm/arch-realview/irqs.h b/include/asm-arm/arch-realview/irqs.h
index c16223c..5a5db56 100644
--- a/include/asm-arm/arch-realview/irqs.h
+++ b/include/asm-arm/arch-realview/irqs.h
@@ -65,6 +65,21 @@
 #define IRQ_AACI		(IRQ_GIC_START + INT_AACI)
 #define IRQ_ETH			(IRQ_GIC_START + INT_ETH)
 #define IRQ_USB			(IRQ_GIC_START + INT_USB)
+#define IRQ_PMU_CPU0		(IRQ_GIC_START + INT_PMU_CPU0)
+#define IRQ_PMU_CPU1		(IRQ_GIC_START + INT_PMU_CPU1)
+#define IRQ_PMU_CPU2		(IRQ_GIC_START + INT_PMU_CPU2)
+#define IRQ_PMU_CPU3		(IRQ_GIC_START + INT_PMU_CPU3)
+#define IRQ_PMU_SCU0		(IRQ_GIC_START + INT_PMU_SCU0)
+#define IRQ_PMU_SCU1		(IRQ_GIC_START + INT_PMU_SCU1)
+#define IRQ_PMU_SCU2		(IRQ_GIC_START + INT_PMU_SCU2)
+#define IRQ_PMU_SCU3		(IRQ_GIC_START + INT_PMU_SCU3)
+#define IRQ_PMU_SCU4		(IRQ_GIC_START + INT_PMU_SCU4)
+#define IRQ_PMU_SCU5		(IRQ_GIC_START + INT_PMU_SCU5)
+#define IRQ_PMU_SCU6		(IRQ_GIC_START + INT_PMU_SCU6)
+#define IRQ_PMU_SCU7		(IRQ_GIC_START + INT_PMU_SCU7)
+
+#define IRQ_EB_IRQ1		(IRQ_GIC_START + INT_EB_IRQ1)
+#define IRQ_EB_IRQ2		(IRQ_GIC_START + INT_EB_IRQ2)
 
 #define IRQMASK_WDOGINT		INTMASK_WDOGINT
 #define IRQMASK_SOFTINT		INTMASK_SOFTINT
@@ -103,4 +118,4 @@
 #define IRQMASK_ETH		INTMASK_ETH
 #define IRQMASK_USB		INTMASK_USB
 
-#define NR_IRQS			(IRQ_GIC_START + 64)
+#define NR_IRQS			(IRQ_GIC_START + 96)
diff --git a/include/asm-arm/arch-realview/platform.h b/include/asm-arm/arch-realview/platform.h
index 18d7c18..6e0eab9 100644
--- a/include/asm-arm/arch-realview/platform.h
+++ b/include/asm-arm/arch-realview/platform.h
@@ -207,11 +207,25 @@
 #define REALVIEW_GIC_CPU_BASE         0x10040000	/* Generic interrupt controller CPU interface */
 #define REALVIEW_GIC_DIST_BASE        0x10041000	/* Generic interrupt controller distributor */
 #else
+#ifdef CONFIG_REALVIEW_MPCORE_REVB
 #define REALVIEW_MPCORE_SCU_BASE	0x10100000	/*  SCU registers */
 #define REALVIEW_GIC_CPU_BASE		0x10100100	/* Generic interrupt controller CPU interface */
 #define REALVIEW_TWD_BASE		0x10100700
 #define REALVIEW_TWD_SIZE		0x00000100
 #define REALVIEW_GIC_DIST_BASE		0x10101000	/* Generic interrupt controller distributor */
+#define REALVIEW_MPCORE_L220_BASE	0x10102000	/* L220 registers */
+#define REALVIEW_MPCORE_SYS_PLD_CTRL1 0xD8		/*  Register offset for MPCore sysctl */
+#else
+#define REALVIEW_MPCORE_SCU_BASE      0x1F000000	/*  SCU registers */
+#define REALVIEW_GIC_CPU_BASE         0x1F000100	/* Generic interrupt controller CPU interface */
+#define REALVIEW_TWD_BASE             0x1F000700
+#define REALVIEW_TWD_SIZE             0x00000100
+#define REALVIEW_GIC_DIST_BASE        0x1F001000	/* Generic interrupt controller distributor */
+#define REALVIEW_MPCORE_L220_BASE     0x1F002000	/* L220 registers */
+#define REALVIEW_MPCORE_SYS_PLD_CTRL1 0x74		/*  Register offset for MPCore sysctl */
+#endif
+#define REALVIEW_GIC1_CPU_BASE        0x10040000	/* Generic interrupt controller CPU interface */
+#define REALVIEW_GIC1_DIST_BASE       0x10041000	/* Generic interrupt controller distributor */
 #endif
 #define REALVIEW_SMC_BASE             0x10080000	/* SMC */
 	/* Reserved 0x10090000 - 0x100EFFFF */
@@ -306,7 +320,11 @@
 #define INT_USB				29	/* USB controller */
 #define INT_TSPENINT			30	/* Touchscreen pen */
 #define INT_TSKPADINT			31	/* Touchscreen keypad */
+
 #else
+
+#define MAX_GIC_NR			2
+
 #define INT_AACI			0
 #define INT_TIMERINT0_1			1
 #define INT_TIMERINT2_3			2
diff --git a/include/asm-arm/arch-realview/scu.h b/include/asm-arm/arch-realview/scu.h
new file mode 100644
index 0000000..cc29364
--- /dev/null
+++ b/include/asm-arm/arch-realview/scu.h
@@ -0,0 +1,8 @@
+#ifndef __ASMARM_ARCH_SCU_H
+#define __ASMARM_ARCH_SCU_H
+
+#include <asm/arch/platform.h>
+
+#define SCU_BASE	REALVIEW_MPCORE_SCU_BASE
+
+#endif
diff --git a/include/asm-arm/arch-s3c2410/dma.h b/include/asm-arm/arch-s3c2410/dma.h
index 58ffa7b..c6e8d8f 100644
--- a/include/asm-arm/arch-s3c2410/dma.h
+++ b/include/asm-arm/arch-s3c2410/dma.h
@@ -51,13 +51,19 @@
 	DMACH_UART0_SRC2,	/* s3c2412 second uart sources */
 	DMACH_UART1_SRC2,
 	DMACH_UART2_SRC2,
+	DMACH_UART3,		/* s3c2443 has extra uart */
+	DMACH_UART3_SRC2,
 	DMACH_MAX,		/* the end entry */
 };
 
 #define DMACH_LOW_LEVEL	(1<<28)	/* use this to specifiy hardware ch no */
 
 /* we have 4 dma channels */
-#define S3C2410_DMA_CHANNELS        (4)
+#ifndef CONFIG_CPU_S3C2443
+#define S3C2410_DMA_CHANNELS		(4)
+#else
+#define S3C2410_DMA_CHANNELS		(6)
+#endif
 
 /* types */
 
@@ -321,6 +327,7 @@
 #define S3C2410_DMA_DCDST       (0x1C)
 #define S3C2410_DMA_DMASKTRIG   (0x20)
 #define S3C2412_DMA_DMAREQSEL	(0x24)
+#define S3C2443_DMA_DMAREQSEL	(0x24)
 
 #define S3C2410_DISRCC_INC	(1<<0)
 #define S3C2410_DISRCC_APB	(1<<1)
@@ -415,4 +422,31 @@
 #define S3C2412_DMAREQSEL_UART2_1	S3C2412_DMAREQSEL_SRC(24)
 
 #endif
+
+#define S3C2443_DMAREQSEL_SRC(x)	((x)<<1)
+
+#define S3C2443_DMAREQSEL_HW		(1)
+
+#define S3C2443_DMAREQSEL_SPI0TX	S3C2443_DMAREQSEL_SRC(0)
+#define S3C2443_DMAREQSEL_SPI0RX	S3C2443_DMAREQSEL_SRC(1)
+#define S3C2443_DMAREQSEL_SPI1TX	S3C2443_DMAREQSEL_SRC(2)
+#define S3C2443_DMAREQSEL_SPI1RX	S3C2443_DMAREQSEL_SRC(3)
+#define S3C2443_DMAREQSEL_I2STX		S3C2443_DMAREQSEL_SRC(4)
+#define S3C2443_DMAREQSEL_I2SRX		S3C2443_DMAREQSEL_SRC(5)
+#define S3C2443_DMAREQSEL_TIMER		S3C2443_DMAREQSEL_SRC(9)
+#define S3C2443_DMAREQSEL_SDI		S3C2443_DMAREQSEL_SRC(10)
+#define S3C2443_DMAREQSEL_XDREQ0	S3C2443_DMAREQSEL_SRC(17)
+#define S3C2443_DMAREQSEL_XDREQ1	S3C2443_DMAREQSEL_SRC(18)
+#define S3C2443_DMAREQSEL_UART0_0	S3C2443_DMAREQSEL_SRC(19)
+#define S3C2443_DMAREQSEL_UART0_1	S3C2443_DMAREQSEL_SRC(20)
+#define S3C2443_DMAREQSEL_UART1_0	S3C2443_DMAREQSEL_SRC(21)
+#define S3C2443_DMAREQSEL_UART1_1	S3C2443_DMAREQSEL_SRC(22)
+#define S3C2443_DMAREQSEL_UART2_0	S3C2443_DMAREQSEL_SRC(23)
+#define S3C2443_DMAREQSEL_UART2_1	S3C2443_DMAREQSEL_SRC(24)
+#define S3C2443_DMAREQSEL_UART3_0	S3C2443_DMAREQSEL_SRC(25)
+#define S3C2443_DMAREQSEL_UART3_1	S3C2443_DMAREQSEL_SRC(26)
+#define S3C2443_DMAREQSEL_PCMOUT	S3C2443_DMAREQSEL_SRC(27)
+#define S3C2443_DMAREQSEL_PCMIN 	S3C2443_DMAREQSEL_SRC(28)
+#define S3C2443_DMAREQSEL_MICIN		S3C2443_DMAREQSEL_SRC(29)
+
 #endif /* __ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-s3c2410/irqs.h b/include/asm-arm/arch-s3c2410/irqs.h
index 4b7cff4..c79cb18 100644
--- a/include/asm-arm/arch-s3c2410/irqs.h
+++ b/include/asm-arm/arch-s3c2410/irqs.h
@@ -34,10 +34,10 @@
 #define IRQ_EINT4t7    S3C2410_IRQ(4)	    /* 20 */
 #define IRQ_EINT8t23   S3C2410_IRQ(5)
 #define IRQ_RESERVED6  S3C2410_IRQ(6)	    /* for s3c2410 */
-#define IRQ_CAM        S3C2410_IRQ(6)	    /* for s3c2440 */
+#define IRQ_CAM        S3C2410_IRQ(6)	    /* for s3c2440,s3c2443 */
 #define IRQ_BATT_FLT   S3C2410_IRQ(7)
 #define IRQ_TICK       S3C2410_IRQ(8)	    /* 24 */
-#define IRQ_WDT	       S3C2410_IRQ(9)
+#define IRQ_WDT	       S3C2410_IRQ(9)	    /* WDT/AC97 for s3c2443 */
 #define IRQ_TIMER0     S3C2410_IRQ(10)
 #define IRQ_TIMER1     S3C2410_IRQ(11)
 #define IRQ_TIMER2     S3C2410_IRQ(12)
@@ -45,7 +45,7 @@
 #define IRQ_TIMER4     S3C2410_IRQ(14)
 #define IRQ_UART2      S3C2410_IRQ(15)
 #define IRQ_LCD	       S3C2410_IRQ(16)	    /* 32 */
-#define IRQ_DMA0       S3C2410_IRQ(17)
+#define IRQ_DMA0       S3C2410_IRQ(17)	    /* IRQ_DMA for s3c2443 */
 #define IRQ_DMA1       S3C2410_IRQ(18)
 #define IRQ_DMA2       S3C2410_IRQ(19)
 #define IRQ_DMA3       S3C2410_IRQ(20)
@@ -94,29 +94,63 @@
  * these need to be ordered in number of appearance in the
  * SUBSRC mask register
 */
-#define IRQ_S3CUART_RX0  S3C2410_IRQ(54)   /* 70 */
-#define IRQ_S3CUART_TX0  S3C2410_IRQ(55)   /* 71 */
-#define IRQ_S3CUART_ERR0 S3C2410_IRQ(56)
 
-#define IRQ_S3CUART_RX1  S3C2410_IRQ(57)
-#define IRQ_S3CUART_TX1  S3C2410_IRQ(58)
-#define IRQ_S3CUART_ERR1 S3C2410_IRQ(59)
+#define S3C2410_IRQSUB(x)	S3C2410_IRQ((x)+54)
 
-#define IRQ_S3CUART_RX2  S3C2410_IRQ(60)
-#define IRQ_S3CUART_TX2  S3C2410_IRQ(61)
-#define IRQ_S3CUART_ERR2 S3C2410_IRQ(62)
+#define IRQ_S3CUART_RX0		S3C2410_IRQSUB(0)	/* 70 */
+#define IRQ_S3CUART_TX0		S3C2410_IRQSUB(1)
+#define IRQ_S3CUART_ERR0	S3C2410_IRQSUB(2)
 
-#define IRQ_TC		 S3C2410_IRQ(63)
-#define IRQ_ADC		 S3C2410_IRQ(64)
+#define IRQ_S3CUART_RX1		S3C2410_IRQSUB(3)	/* 73 */
+#define IRQ_S3CUART_TX1		S3C2410_IRQSUB(4)
+#define IRQ_S3CUART_ERR1	S3C2410_IRQSUB(5)
+
+#define IRQ_S3CUART_RX2		S3C2410_IRQSUB(6)	/* 76 */
+#define IRQ_S3CUART_TX2		S3C2410_IRQSUB(7)
+#define IRQ_S3CUART_ERR2	S3C2410_IRQSUB(8)
+
+#define IRQ_TC			S3C2410_IRQSUB(9)
+#define IRQ_ADC			S3C2410_IRQSUB(10)
 
 /* extra irqs for s3c2440 */
 
-#define IRQ_S3C2440_CAM_C	S3C2410_IRQ(65)
-#define IRQ_S3C2440_CAM_P	S3C2410_IRQ(66)
-#define IRQ_S3C2440_WDT		S3C2410_IRQ(67)
-#define IRQ_S3C2440_AC97	S3C2410_IRQ(68)
+#define IRQ_S3C2440_CAM_C	S3C2410_IRQSUB(11)	/* S3C2443 too */
+#define IRQ_S3C2440_CAM_P	S3C2410_IRQSUB(12)	/* S3C2443 too */
+#define IRQ_S3C2440_WDT		S3C2410_IRQSUB(13)
+#define IRQ_S3C2440_AC97	S3C2410_IRQSUB(14)
 
+/* irqs for s3c2443 */
+
+#define IRQ_S3C2443_DMA		S3C2410_IRQ(17)		/* IRQ_DMA1 */
+#define IRQ_S3C2443_UART3	S3C2410_IRQ(18)		/* IRQ_DMA2 */
+#define IRQ_S3C2443_CFCON	S3C2410_IRQ(19)		/* IRQ_DMA3 */
+#define IRQ_S3C2443_SDI1	S3C2410_IRQ(20)		/* IRQ_SDI */
+#define IRQ_S3C2443_NAND	S3C2410_IRQ(24)		/* reserved */
+
+#define IRQ_S3C2443_LCD1	S3C2410_IRQSUB(14)
+#define IRQ_S3C2443_LCD2	S3C2410_IRQSUB(15)
+#define IRQ_S3C2443_LCD3	S3C2410_IRQSUB(16)
+#define IRQ_S3C2443_LCD4	S3C2410_IRQSUB(17)
+
+#define IRQ_S3C2443_DMA0	S3C2410_IRQSUB(18)
+#define IRQ_S3C2443_DMA1	S3C2410_IRQSUB(19)
+#define IRQ_S3C2443_DMA2	S3C2410_IRQSUB(20)
+#define IRQ_S3C2443_DMA3	S3C2410_IRQSUB(21)
+#define IRQ_S3C2443_DMA4	S3C2410_IRQSUB(22)
+#define IRQ_S3C2443_DMA5	S3C2410_IRQSUB(23)
+
+/* UART3 */
+#define IRQ_S3C2443_RX3		S3C2410_IRQSUB(24)
+#define IRQ_S3C2443_TX3		S3C2410_IRQSUB(25)
+#define IRQ_S3C2443_ERR3	S3C2410_IRQSUB(26)
+
+#define IRQ_S3C2443_WDT		S3C2410_IRQSUB(27)
+#define IRQ_S3C2443_AC97	S3C2410_IRQSUB(28)
+
+#ifdef CONFIG_CPU_S3C2443
+#define NR_IRQS (IRQ_S3C2443_AC97+1)
+#else
 #define NR_IRQS (IRQ_S3C2440_AC97+1)
-
+#endif
 
 #endif /* __ASM_ARCH_IRQ_H */
diff --git a/include/asm-arm/arch-s3c2410/regs-adc.h b/include/asm-arm/arch-s3c2410/regs-adc.h
index 3196a28..c7f2319 100644
--- a/include/asm-arm/arch-s3c2410/regs-adc.h
+++ b/include/asm-arm/arch-s3c2410/regs-adc.h
@@ -41,7 +41,7 @@
 #define S3C2410_ADCTSC_XP_SEN		(1<<4)
 #define S3C2410_ADCTSC_PULL_UP_DISABLE	(1<<3)
 #define S3C2410_ADCTSC_AUTO_PST		(1<<2)
-#define S3C2410_ADCTSC_XY_PST		(0x3<<0)
+#define S3C2410_ADCTSC_XY_PST(x)	(((x)&0x3)<<0)
 
 /* ADCDAT0 Bits */
 #define S3C2410_ADCDAT0_UPDOWN		(1<<15)
diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h
index eae9169..dea578b 100644
--- a/include/asm-arm/arch-s3c2410/regs-gpio.h
+++ b/include/asm-arm/arch-s3c2410/regs-gpio.h
@@ -201,7 +201,7 @@
 #define S3C2400_GPBDAT	   S3C2410_GPIOREG(0x0C)
 #define S3C2400_GPBUP	   S3C2410_GPIOREG(0x10)
 
-/* no i/o pin in port b can have value 3! */
+/* no i/o pin in port b can have value 3 (unless it is a s3c2443) ! */
 
 #define S3C2410_GPB0         S3C2410_GPIONO(S3C2410_GPIO_BANKB, 0)
 #define S3C2410_GPB0_INP     (0x00 << 0)
@@ -242,6 +242,7 @@
 #define S3C2410_GPB5_INP     (0x00 << 10)
 #define S3C2410_GPB5_OUTP    (0x01 << 10)
 #define S3C2410_GPB5_nXBACK  (0x02 << 10)
+#define S3C2443_GPB5_XBACK   (0x03 << 10)
 #define S3C2400_GPB5_DATA21  (0x02 << 10)
 #define S3C2400_GPB5_nCTS1   (0x03 << 10)
 
@@ -249,6 +250,7 @@
 #define S3C2410_GPB6_INP     (0x00 << 12)
 #define S3C2410_GPB6_OUTP    (0x01 << 12)
 #define S3C2410_GPB6_nXBREQ  (0x02 << 12)
+#define S3C2443_GPB6_XBREQ   (0x03 << 12)
 #define S3C2400_GPB6_DATA22  (0x02 << 12)
 #define S3C2400_GPB6_nRTS1   (0x03 << 12)
 
@@ -256,6 +258,7 @@
 #define S3C2410_GPB7_INP     (0x00 << 14)
 #define S3C2410_GPB7_OUTP    (0x01 << 14)
 #define S3C2410_GPB7_nXDACK1 (0x02 << 14)
+#define S3C2443_GPB7_XDACK1  (0x03 << 14)
 #define S3C2400_GPB7_DATA23  (0x02 << 14)
 
 #define S3C2410_GPB8         S3C2410_GPIONO(S3C2410_GPIO_BANKB, 8)
@@ -268,6 +271,7 @@
 #define S3C2410_GPB9_INP     (0x00 << 18)
 #define S3C2410_GPB9_OUTP    (0x01 << 18)
 #define S3C2410_GPB9_nXDACK0 (0x02 << 18)
+#define S3C2443_GPB9_XDACK0  (0x03 << 18)
 #define S3C2400_GPB9_DATA25  (0x02 << 18)
 #define S3C2400_GPB9_I2SSDI  (0x03 << 18)
 
@@ -275,6 +279,7 @@
 #define S3C2410_GPB10_INP    (0x00 << 20)
 #define S3C2410_GPB10_OUTP   (0x01 << 20)
 #define S3C2410_GPB10_nXDRE0 (0x02 << 20)
+#define S3C2443_GPB10_XDREQ0 (0x03 << 20)
 #define S3C2400_GPB10_DATA26 (0x02 << 20)
 #define S3C2400_GPB10_nSS    (0x03 << 20)
 
@@ -556,6 +561,7 @@
 #define S3C2410_GPE0_INP       (0x00 << 0)
 #define S3C2410_GPE0_OUTP      (0x01 << 0)
 #define S3C2410_GPE0_I2SLRCK   (0x02 << 0)
+#define S3C2443_GPE0_AC_nRESET (0x03 << 0)
 #define S3C2400_GPE0_EINT0     (0x02 << 0)
 #define S3C2410_GPE0_MASK      (0x03 << 0)
 
@@ -563,6 +569,7 @@
 #define S3C2410_GPE1_INP       (0x00 << 2)
 #define S3C2410_GPE1_OUTP      (0x01 << 2)
 #define S3C2410_GPE1_I2SSCLK   (0x02 << 2)
+#define S3C2443_GPE1_AC_SYNC   (0x03 << 2)
 #define S3C2400_GPE1_EINT1     (0x02 << 2)
 #define S3C2400_GPE1_nSS       (0x03 << 2)
 #define S3C2410_GPE1_MASK      (0x03 << 2)
@@ -571,6 +578,7 @@
 #define S3C2410_GPE2_INP       (0x00 << 4)
 #define S3C2410_GPE2_OUTP      (0x01 << 4)
 #define S3C2410_GPE2_CDCLK     (0x02 << 4)
+#define S3C2443_GPE2_AC_BITCLK (0x03 << 4)
 #define S3C2400_GPE2_EINT2     (0x02 << 4)
 #define S3C2400_GPE2_I2SSDI    (0x03 << 4)
 
@@ -578,6 +586,7 @@
 #define S3C2410_GPE3_INP       (0x00 << 6)
 #define S3C2410_GPE3_OUTP      (0x01 << 6)
 #define S3C2410_GPE3_I2SSDI    (0x02 << 6)
+#define S3C2443_GPE3_AC_SDI    (0x03 << 6)
 #define S3C2400_GPE3_EINT3     (0x02 << 6)
 #define S3C2400_GPE3_nCTS1     (0x03 << 6)
 #define S3C2410_GPE3_nSS0      (0x03 << 6)
@@ -587,6 +596,7 @@
 #define S3C2410_GPE4_INP       (0x00 << 8)
 #define S3C2410_GPE4_OUTP      (0x01 << 8)
 #define S3C2410_GPE4_I2SSDO    (0x02 << 8)
+#define S3C2443_GPE4_AC_SDO    (0x03 << 8)
 #define S3C2400_GPE4_EINT4     (0x02 << 8)
 #define S3C2400_GPE4_nRTS1     (0x03 << 8)
 #define S3C2410_GPE4_I2SSDI    (0x03 << 8)
@@ -596,6 +606,7 @@
 #define S3C2410_GPE5_INP       (0x00 << 10)
 #define S3C2410_GPE5_OUTP      (0x01 << 10)
 #define S3C2410_GPE5_SDCLK     (0x02 << 10)
+#define S3C2443_GPE5_SD1_CLK   (0x02 << 10)
 #define S3C2400_GPE5_EINT5     (0x02 << 10)
 #define S3C2400_GPE5_TCLK1     (0x03 << 10)
 
@@ -603,24 +614,32 @@
 #define S3C2410_GPE6_INP       (0x00 << 12)
 #define S3C2410_GPE6_OUTP      (0x01 << 12)
 #define S3C2410_GPE6_SDCMD     (0x02 << 12)
+#define S3C2443_GPE6_SD1_CMD   (0x02 << 12)
+#define S3C2443_GPE6_AC_BITCLK (0x03 << 12)
 #define S3C2400_GPE6_EINT6     (0x02 << 12)
 
 #define S3C2410_GPE7           S3C2410_GPIONO(S3C2410_GPIO_BANKE, 7)
 #define S3C2410_GPE7_INP       (0x00 << 14)
 #define S3C2410_GPE7_OUTP      (0x01 << 14)
 #define S3C2410_GPE7_SDDAT0    (0x02 << 14)
+#define S3C2443_GPE5_SD1_DAT0  (0x02 << 14)
+#define S3C2443_GPE7_AC_SDI    (0x03 << 14)
 #define S3C2400_GPE7_EINT7     (0x02 << 14)
 
 #define S3C2410_GPE8           S3C2410_GPIONO(S3C2410_GPIO_BANKE, 8)
 #define S3C2410_GPE8_INP       (0x00 << 16)
 #define S3C2410_GPE8_OUTP      (0x01 << 16)
 #define S3C2410_GPE8_SDDAT1    (0x02 << 16)
+#define S3C2443_GPE8_SD1_DAT1  (0x02 << 16)
+#define S3C2443_GPE8_AC_SDO    (0x03 << 16)
 #define S3C2400_GPE8_nXDACK0   (0x02 << 16)
 
 #define S3C2410_GPE9           S3C2410_GPIONO(S3C2410_GPIO_BANKE, 9)
 #define S3C2410_GPE9_INP       (0x00 << 18)
 #define S3C2410_GPE9_OUTP      (0x01 << 18)
 #define S3C2410_GPE9_SDDAT2    (0x02 << 18)
+#define S3C2443_GPE9_SD1_DAT2  (0x02 << 18)
+#define S3C2443_GPE9_AC_SYNC   (0x03 << 18)
 #define S3C2400_GPE9_nXDACK1   (0x02 << 18)
 #define S3C2400_GPE9_nXBACK    (0x03 << 18)
 
@@ -628,6 +647,8 @@
 #define S3C2410_GPE10_INP      (0x00 << 20)
 #define S3C2410_GPE10_OUTP     (0x01 << 20)
 #define S3C2410_GPE10_SDDAT3   (0x02 << 20)
+#define S3C2443_GPE10_SD1_DAT3 (0x02 << 20)
+#define S3C2443_GPE10_AC_nRESET (0x03 << 20)
 #define S3C2400_GPE10_nXDREQ0  (0x02 << 20)
 
 #define S3C2410_GPE11          S3C2410_GPIONO(S3C2410_GPIO_BANKE, 11)
@@ -796,6 +817,7 @@
 #define S3C2400_GPG4_MMCCLK   (0x02 << 8)
 #define S3C2400_GPG4_I2SSDI   (0x03 << 8)
 #define S3C2410_GPG4_LCDPWREN (0x03 << 8)
+#define S3C2443_GPG4_LCDPWRDN (0x03 << 8)
 
 #define S3C2410_GPG5          S3C2410_GPIONO(S3C2410_GPIO_BANKG, 5)
 #define S3C2410_GPG5_INP      (0x00 << 10)
@@ -803,7 +825,7 @@
 #define S3C2410_GPG5_EINT13   (0x02 << 10)
 #define S3C2400_GPG5_MMCCMD   (0x02 << 10)
 #define S3C2400_GPG5_IICSDA   (0x03 << 10)
-#define S3C2410_GPG5_SPIMISO1 (0x03 << 10)
+#define S3C2410_GPG5_SPIMISO1 (0x03 << 10)	/* not s3c2443 */
 
 #define S3C2410_GPG6          S3C2410_GPIONO(S3C2410_GPIO_BANKG, 6)
 #define S3C2410_GPG6_INP      (0x00 << 12)
@@ -845,6 +867,7 @@
 #define S3C2410_GPG11_OUTP    (0x01 << 22)
 #define S3C2410_GPG11_EINT19  (0x02 << 22)
 #define S3C2410_GPG11_TCLK1   (0x03 << 22)
+#define S3C2443_GPG11_CF_nIREQ (0x03 << 22)
 
 #define S3C2410_GPG12         S3C2410_GPIONO(S3C2410_GPIO_BANKG, 12)
 #define S3C2410_GPG12_INP     (0x00 << 24)
@@ -852,25 +875,28 @@
 #define S3C2410_GPG12_EINT20  (0x02 << 24)
 #define S3C2410_GPG12_XMON    (0x03 << 24)
 #define S3C2442_GPG12_nSPICS0 (0x03 << 24)
+#define S3C2443_GPG12_nINPACK (0x03 << 24)
 
 #define S3C2410_GPG13         S3C2410_GPIONO(S3C2410_GPIO_BANKG, 13)
 #define S3C2410_GPG13_INP     (0x00 << 26)
 #define S3C2410_GPG13_OUTP    (0x01 << 26)
 #define S3C2410_GPG13_EINT21  (0x02 << 26)
 #define S3C2410_GPG13_nXPON   (0x03 << 26)
+#define S3C2443_GPG13_CF_nREG (0x03 << 26)
 
 #define S3C2410_GPG14         S3C2410_GPIONO(S3C2410_GPIO_BANKG, 14)
 #define S3C2410_GPG14_INP     (0x00 << 28)
 #define S3C2410_GPG14_OUTP    (0x01 << 28)
 #define S3C2410_GPG14_EINT22  (0x02 << 28)
 #define S3C2410_GPG14_YMON    (0x03 << 28)
+#define S3C2443_GPG14_CF_RESET (0x03 << 28)
 
 #define S3C2410_GPG15         S3C2410_GPIONO(S3C2410_GPIO_BANKG, 15)
 #define S3C2410_GPG15_INP     (0x00 << 30)
 #define S3C2410_GPG15_OUTP    (0x01 << 30)
 #define S3C2410_GPG15_EINT23  (0x02 << 30)
 #define S3C2410_GPG15_nYPON   (0x03 << 30)
-
+#define S3C2443_GPG15_CF_PWR  (0x03 << 30)
 
 #define S3C2410_GPG_PUPDIS(x)  (1<<(x))
 
diff --git a/include/asm-arm/arch-s3c2410/regs-s3c2443-clock.h b/include/asm-arm/arch-s3c2410/regs-s3c2443-clock.h
new file mode 100644
index 0000000..ff0536d
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/regs-s3c2443-clock.h
@@ -0,0 +1,194 @@
+/* linux/include/asm-arm/arch-s3c2410/regs-clock.h
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2443 clock register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_S3C2443_CLOCK
+#define __ASM_ARM_REGS_S3C2443_CLOCK
+
+#define S3C2443_CLKREG(x)		((x) + S3C24XX_VA_CLKPWR)
+
+#define S3C2443_PLLCON_MDIVSHIFT	16
+#define S3C2443_PLLCON_PDIVSHIFT	8
+#define S3C2443_PLLCON_SDIVSHIFT	0
+#define S3C2443_PLLCON_MDIVMASK		((1<<(1+(23-16)))-1)
+#define S3C2443_PLLCON_PDIVMASK		((1<<(1+(9-8)))-1)
+#define S3C2443_PLLCON_SDIVMASK		(3)
+
+#define S3C2443_MPLLCON			S3C2443_CLKREG(0x10)
+#define S3C2443_EPLLCON			S3C2443_CLKREG(0x18)
+#define S3C2443_CLKSRC			S3C2443_CLKREG(0x20)
+#define S3C2443_CLKDIV0			S3C2443_CLKREG(0x24)
+#define S3C2443_CLKDIV1			S3C2443_CLKREG(0x28)
+#define S3C2443_HCLKCON			S3C2443_CLKREG(0x30)
+#define S3C2443_PCLKCON			S3C2443_CLKREG(0x34)
+#define S3C2443_SCLKCON			S3C2443_CLKREG(0x38)
+#define S3C2443_PWRMODE			S3C2443_CLKREG(0x40)
+#define S3C2443_SWRST			S3C2443_CLKREG(0x44)
+#define S3C2443_BUSPRI0			S3C2443_CLKREG(0x50)
+#define S3C2443_SYSID			S3C2443_CLKREG(0x5C)
+#define S3C2443_PWRCFG			S3C2443_CLKREG(0x60)
+#define S3C2443_RSTCON			S3C2443_CLKREG(0x64)
+
+#define S3C2443_SWRST_RESET		(0x533c2443)
+
+#define S3C2443_PLLCON_OFF		(1<<24)
+
+#define S3C2443_CLKSRC_I2S_EXT		(1<<14)
+#define S3C2443_CLKSRC_I2S_EPLLDIV	(0<<14)
+#define S3C2443_CLKSRC_I2S_EPLLREF	(2<<14)
+#define S3C2443_CLKSRC_I2S_EPLLREF3	(3<<14)
+#define S3C2443_CLKSRC_I2S_MASK		(3<<14)
+
+#define S3C2443_CLKSRC_EPLLREF_XTAL	(2<<8)
+#define S3C2443_CLKSRC_EPLLREF_EXTCLK	(3<<8)
+#define S3C2443_CLKSRC_EPLLREF_MPLLREF	(0<<8)
+#define S3C2443_CLKSRC_EPLLREF_MPLLREF2	(1<<8)
+#define S3C2443_CLKSRC_EPLLREF_MASK	(3<<8)
+
+#define S3C2443_CLKSRC_ESYSCLK_EPLL	(1<<6)
+#define S3C2443_CLKSRC_MSYSCLK_MPLL	(1<<4)
+#define S3C2443_CLKSRC_EXTCLK_DIV	(1<<3)
+
+#define S3C2443_CLKDIV0_DVS		(1<<13)
+#define S3C2443_CLKDIV0_HALF_HCLK	(1<<3)
+#define S3C2443_CLKDIV0_HALF_PCLK	(1<<2)
+
+#define S3C2443_CLKDIV0_HCLKDIV_MASK	(3<<0)
+
+#define S3C2443_CLKDIV0_EXTDIV_MASK	(3<<6)
+#define S3C2443_CLKDIV0_EXTDIV_SHIFT	(6)
+
+#define S3C2443_CLKDIV0_PREDIV_MASK	(3<<4)
+#define S3C2443_CLKDIV0_PREDIV_SHIFT	(4)
+
+#define S3C2443_CLKDIV0_ARMDIV_MASK	(15<<9)
+#define S3C2443_CLKDIV0_ARMDIV_SHIFT	(9)
+#define S3C2443_CLKDIV0_ARMDIV_1	(0<<9)
+#define S3C2443_CLKDIV0_ARMDIV_2	(8<<9)
+#define S3C2443_CLKDIV0_ARMDIV_3	(2<<9)
+#define S3C2443_CLKDIV0_ARMDIV_4	(9<<9)
+#define S3C2443_CLKDIV0_ARMDIV_6	(10<<9)
+#define S3C2443_CLKDIV0_ARMDIV_8	(11<<9)
+#define S3C2443_CLKDIV0_ARMDIV_12	(13<<9)
+#define S3C2443_CLKDIV0_ARMDIV_16	(15<<9)
+
+/* S3C2443_CLKDIV1 */
+
+#define S3C2443_CLKDIV1_CAMDIV_MASK	(15<<26)
+#define S3C2443_CLKDIV1_CAMDIV_SHIFT	(26)
+
+#define S3C2443_CLKDIV1_HSSPIDIV_MASK	(3<<24)
+#define S3C2443_CLKDIV1_HSSPIDIV_SHIFT	(24)
+
+#define S3C2443_CLKDIV1_DISPDIV_MASK	(0xff<<16)
+#define S3C2443_CLKDIV1_DISPDIV_SHIFT	(16)
+
+#define S3C2443_CLKDIV1_I2SDIV_MASK	(15<<12)
+#define S3C2443_CLKDIV1_I2SDIV_SHIFT	(12)
+
+#define S3C2443_CLKDIV1_UARTDIV_MASK	(15<<8)
+#define S3C2443_CLKDIV1_UARTDIV_SHIFT	(8)
+
+#define S3C2443_CLKDIV1_HSMMCDIV_MASK	(3<<6)
+#define S3C2443_CLKDIV1_HSMMCDIV_SHIFT	(6)
+
+#define S3C2443_CLKDIV1_USBHOSTDIV_MASK	(3<<4)
+#define S3C2443_CLKDIV1_USBHOSTDIV_SHIFT (4)
+
+#define S3C2443_CLKCON_NAND
+
+#define S3C2443_HCLKCON_DMA0		(1<<0)
+#define S3C2443_HCLKCON_DMA1		(1<<1)
+#define S3C2443_HCLKCON_DMA2		(1<<2)
+#define S3C2443_HCLKCON_DMA3		(1<<3)
+#define S3C2443_HCLKCON_DMA4		(1<<4)
+#define S3C2443_HCLKCON_DMA5		(1<<5)
+#define S3C2443_HCLKCON_CAMIF		(1<<8)
+#define S3C2443_HCLKCON_DISP		(1<<9)
+#define S3C2443_HCLKCON_LCDC		(1<<10)
+#define S3C2443_HCLKCON_USBH		(1<<11)
+#define S3C2443_HCLKCON_USBD		(1<<12)
+#define S3C2443_HCLKCON_HSMMC		(1<<16)
+#define S3C2443_HCLKCON_CFC		(1<<17)
+#define S3C2443_HCLKCON_SSMC		(1<<18)
+#define S3C2443_HCLKCON_DRAMC		(1<<19)
+
+#define S3C2443_PCLKCON_UART0		(1<<0)
+#define S3C2443_PCLKCON_UART1		(1<<1)
+#define S3C2443_PCLKCON_UART2		(1<<2)
+#define S3C2443_PCLKCON_UART3		(1<<3)
+#define S3C2443_PCLKCON_IIC		(1<<4)
+#define S3C2443_PCLKCON_SDI		(1<<5)
+#define S3C2443_PCLKCON_ADC		(1<<7)
+#define S3C2443_PCLKCON_IIS		(1<<9)
+#define S3C2443_PCLKCON_PWMT		(1<<10)
+#define S3C2443_PCLKCON_WDT		(1<<11)
+#define S3C2443_PCLKCON_RTC		(1<<12)
+#define S3C2443_PCLKCON_GPIO		(1<<13)
+#define S3C2443_PCLKCON_SPI0		(1<<14)
+#define S3C2443_PCLKCON_SPI1		(1<<15)
+
+#define S3C2443_SCLKCON_DDRCLK		(1<<16)
+#define S3C2443_SCLKCON_SSMCCLK		(1<<15)
+#define S3C2443_SCLKCON_HSSPICLK	(1<<14)
+#define S3C2443_SCLKCON_HSMMCCLK_EXT	(1<<13)
+#define S3C2443_SCLKCON_HSMMCCLK_EPLL	(1<<12)
+#define S3C2443_SCLKCON_CAMCLK		(1<<11)
+#define S3C2443_SCLKCON_DISPCLK		(1<<10)
+#define S3C2443_SCLKCON_I2SCLK		(1<<9)
+#define S3C2443_SCLKCON_UARTCLK		(1<<8)
+#define S3C2443_SCLKCON_USBHOST		(1<<1)
+
+#include <asm/div64.h>
+
+static inline unsigned int
+s3c2443_get_mpll(unsigned int pllval, unsigned int baseclk)
+{
+	unsigned int mdiv, pdiv, sdiv;
+	uint64_t fvco;
+
+	mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT;
+	pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT;
+	sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT;
+
+	mdiv &= S3C2443_PLLCON_MDIVMASK;
+	pdiv &= S3C2443_PLLCON_PDIVMASK;
+	sdiv &= S3C2443_PLLCON_SDIVMASK;
+
+	fvco = (uint64_t)baseclk * (2 * (mdiv + 8));
+	do_div(fvco, pdiv << sdiv);
+
+	return (unsigned int)fvco;
+}
+
+static inline unsigned int
+s3c2443_get_epll(unsigned int pllval, unsigned int baseclk)
+{
+	unsigned int mdiv, pdiv, sdiv;
+	uint64_t fvco;
+
+	mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT;
+	pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT;
+	sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT;
+
+	mdiv &= S3C2443_PLLCON_MDIVMASK;
+	pdiv &= S3C2443_PLLCON_PDIVMASK;
+	sdiv &= S3C2443_PLLCON_SDIVMASK;
+
+	fvco = (uint64_t)baseclk * (mdiv + 8);
+	do_div(fvco, (pdiv + 2) << sdiv);
+
+	return (unsigned int)fvco;
+}
+
+#endif /*  __ASM_ARM_REGS_S3C2443_CLOCK */
+
diff --git a/include/asm-arm/arch-s3c2410/regs-serial.h b/include/asm-arm/arch-s3c2410/regs-serial.h
index 46f5240..8946702 100644
--- a/include/asm-arm/arch-s3c2410/regs-serial.h
+++ b/include/asm-arm/arch-s3c2410/regs-serial.h
@@ -35,10 +35,12 @@
 #define S3C24XX_VA_UART0      (S3C24XX_VA_UART)
 #define S3C24XX_VA_UART1      (S3C24XX_VA_UART + 0x4000 )
 #define S3C24XX_VA_UART2      (S3C24XX_VA_UART + 0x8000 )
+#define S3C24XX_VA_UART3      (S3C24XX_VA_UART + 0xC000 )
 
 #define S3C2410_PA_UART0      (S3C24XX_PA_UART)
 #define S3C2410_PA_UART1      (S3C24XX_PA_UART + 0x4000 )
 #define S3C2410_PA_UART2      (S3C24XX_PA_UART + 0x8000 )
+#define S3C2443_PA_UART3      (S3C24XX_PA_UART + 0xC000 )
 
 #define S3C2410_URXH	  (0x24)
 #define S3C2410_UTXH	  (0x20)
@@ -73,6 +75,8 @@
 #define S3C2440_UCON_UCLK	  (1<<10)
 #define S3C2440_UCON_PCLK2	  (2<<10)
 #define S3C2440_UCON_FCLK	  (3<<10)
+#define S3C2443_UCON_EPLL	  (3<<10)
+
 #define S3C2440_UCON2_FCLK_EN	  (1<<15)
 #define S3C2440_UCON0_DIVMASK	  (15 << 12)
 #define S3C2440_UCON1_DIVMASK	  (15 << 12)
@@ -93,6 +97,8 @@
 #define S3C2410_UCON_TXIRQMODE	  (1<<2)
 #define S3C2410_UCON_RXIRQMODE	  (1<<0)
 #define S3C2410_UCON_RXFIFO_TOI	  (1<<7)
+#define S3C2443_UCON_RXERR_IRQEN  (1<<6)
+#define S3C2443_UCON_LOOPBACK	  (1<<5)
 
 #define S3C2410_UCON_DEFAULT	  (S3C2410_UCON_TXILEVEL  | \
 				   S3C2410_UCON_RXILEVEL  | \
@@ -127,7 +133,7 @@
 #define	S3C2410_UMCOM_AFC	  (1<<4)
 #define	S3C2410_UMCOM_RTS_LOW	  (1<<0)
 
-#define S3C2412_UMCON_AFC_63	(0<<5)
+#define S3C2412_UMCON_AFC_63	(0<<5)		/* same as s3c2443 */
 #define S3C2412_UMCON_AFC_56	(1<<5)
 #define S3C2412_UMCON_AFC_48	(2<<5)
 #define S3C2412_UMCON_AFC_40	(3<<5)
@@ -143,6 +149,7 @@
 #define S3C2410_UFSTAT_RXMASK	  (15<<0)
 #define S3C2410_UFSTAT_RXSHIFT	  (0)
 
+/* UFSTAT S3C2443 same as S3C2440 */
 #define S3C2440_UFSTAT_TXFULL	  (1<<14)
 #define S3C2440_UFSTAT_RXFULL	  (1<<6)
 #define S3C2440_UFSTAT_TXSHIFT	  (8)
@@ -157,6 +164,8 @@
 #define S3C2410_UERSTAT_OVERRUN	  (1<<0)
 #define S3C2410_UERSTAT_FRAME	  (1<<2)
 #define S3C2410_UERSTAT_BREAK	  (1<<3)
+#define S3C2443_UERSTAT_PARITY	  (1<<1)
+
 #define S3C2410_UERSTAT_ANY	  (S3C2410_UERSTAT_OVERRUN | \
 				   S3C2410_UERSTAT_FRAME | \
 				   S3C2410_UERSTAT_BREAK)
@@ -164,6 +173,8 @@
 #define S3C2410_UMSTAT_CTS	  (1<<0)
 #define S3C2410_UMSTAT_DeltaCTS	  (1<<2)
 
+#define S3C2443_DIVSLOT		  (0x2C)
+
 #ifndef __ASSEMBLY__
 
 /* struct s3c24xx_uart_clksrc
diff --git a/include/asm-arm/arch-s3c2410/reset.h b/include/asm-arm/arch-s3c2410/reset.h
new file mode 100644
index 0000000..4f866cd
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/reset.h
@@ -0,0 +1,22 @@
+/* linux/include/asm-arm/arch-s3c2410/reset.h
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 CPU reset controls
+*/
+
+#ifndef __ASM_ARCH_RESET_H
+#define __ASM_ARCH_RESET_H __FILE__
+
+/* This allows the over-ride of the default reset code
+*/
+
+extern void (*s3c24xx_reset_hook)(void);
+
+#endif /* __ASM_ARCH_RESET_H */
diff --git a/include/asm-arm/arch-s3c2410/system.h b/include/asm-arm/arch-s3c2410/system.h
index ecf250d..1c74ef1 100644
--- a/include/asm-arm/arch-s3c2410/system.h
+++ b/include/asm-arm/arch-s3c2410/system.h
@@ -15,15 +15,16 @@
 
 #include <asm/arch/map.h>
 #include <asm/arch/idle.h>
+#include <asm/arch/reset.h>
 
 #include <asm/arch/regs-watchdog.h>
 #include <asm/arch/regs-clock.h>
 
 void (*s3c24xx_idle)(void);
+void (*s3c24xx_reset_hook)(void);
 
 void s3c24xx_default_idle(void)
 {
-	void __iomem *reg = S3C2410_CLKCON;
 	unsigned long tmp;
 	int i;
 
@@ -33,16 +34,18 @@
 
 	/* Warning: going into idle state upsets jtag scanning */
 
-	__raw_writel(__raw_readl(reg) | (1<<2), reg);
+	__raw_writel(__raw_readl(S3C2410_CLKCON) | S3C2410_CLKCON_IDLE,
+		     S3C2410_CLKCON);
 
 	/* the samsung port seems to do a loop and then unset idle.. */
 	for (i = 0; i < 50; i++) {
-		tmp += __raw_readl(reg); /* ensure loop not optimised out */
+		tmp += __raw_readl(S3C2410_CLKCON); /* ensure loop not optimised out */
 	}
 
 	/* this bit is not cleared on re-start... */
 
-	__raw_writel(__raw_readl(reg) & ~(1<<2), reg);
+	__raw_writel(__raw_readl(S3C2410_CLKCON) & ~S3C2410_CLKCON_IDLE,
+		     S3C2410_CLKCON);
 }
 
 static void arch_idle(void)
@@ -53,7 +56,6 @@
 		s3c24xx_default_idle();
 }
 
-
 static void
 arch_reset(char mode)
 {
@@ -61,6 +63,9 @@
 		cpu_reset(0);
 	}
 
+	if (s3c24xx_reset_hook)
+		s3c24xx_reset_hook();
+
 	printk("arch_reset: attempting watchdog reset\n");
 
 	__raw_writel(0, S3C2410_WTCON);	  /* disable watchdog, to be safe  */
diff --git a/include/asm-arm/arch-s3c2410/udc.h b/include/asm-arm/arch-s3c2410/udc.h
new file mode 100644
index 0000000..e59ec33
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/udc.h
@@ -0,0 +1,36 @@
+/* linux/include/asm/arch-s3c2410/udc.h
+ *
+ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ *  Changelog:
+ *	14-Mar-2005	RTP	Created file
+ *	02-Aug-2005	RTP	File rename
+ *	07-Sep-2005	BJD	Minor cleanups, changed cmd to enum
+ *	18-Jan-2007	HMW	Add per-platform vbus_draw function
+*/
+
+#ifndef __ASM_ARM_ARCH_UDC_H
+#define __ASM_ARM_ARCH_UDC_H
+
+enum s3c2410_udc_cmd_e {
+	S3C2410_UDC_P_ENABLE	= 1,	/* Pull-up enable        */
+	S3C2410_UDC_P_DISABLE	= 2,	/* Pull-up disable       */
+	S3C2410_UDC_P_RESET	= 3,	/* UDC reset, in case of */
+};
+
+struct s3c2410_udc_mach_info {
+	void	(*udc_command)(enum s3c2410_udc_cmd_e);
+ 	void	(*vbus_draw)(unsigned int ma);
+	unsigned int vbus_pin;
+	unsigned char vbus_pin_inverted;
+};
+
+extern void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *);
+
+#endif /* __ASM_ARM_ARCH_UDC_H */
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
index 5f531ea..afad32c 100644
--- a/include/asm-arm/cacheflush.h
+++ b/include/asm-arm/cacheflush.h
@@ -185,9 +185,15 @@
 	void (*coherent_user_range)(unsigned long, unsigned long);
 	void (*flush_kern_dcache_page)(void *);
 
-	void (*dma_inv_range)(unsigned long, unsigned long);
-	void (*dma_clean_range)(unsigned long, unsigned long);
-	void (*dma_flush_range)(unsigned long, unsigned long);
+	void (*dma_inv_range)(const void *, const void *);
+	void (*dma_clean_range)(const void *, const void *);
+	void (*dma_flush_range)(const void *, const void *);
+};
+
+struct outer_cache_fns {
+	void (*inv_range)(unsigned long, unsigned long);
+	void (*clean_range)(unsigned long, unsigned long);
+	void (*flush_range)(unsigned long, unsigned long);
 };
 
 /*
@@ -240,9 +246,40 @@
 #define dmac_clean_range		__glue(_CACHE,_dma_clean_range)
 #define dmac_flush_range		__glue(_CACHE,_dma_flush_range)
 
-extern void dmac_inv_range(unsigned long, unsigned long);
-extern void dmac_clean_range(unsigned long, unsigned long);
-extern void dmac_flush_range(unsigned long, unsigned long);
+extern void dmac_inv_range(const void *, const void *);
+extern void dmac_clean_range(const void *, const void *);
+extern void dmac_flush_range(const void *, const void *);
+
+#endif
+
+#ifdef CONFIG_OUTER_CACHE
+
+extern struct outer_cache_fns outer_cache;
+
+static inline void outer_inv_range(unsigned long start, unsigned long end)
+{
+	if (outer_cache.inv_range)
+		outer_cache.inv_range(start, end);
+}
+static inline void outer_clean_range(unsigned long start, unsigned long end)
+{
+	if (outer_cache.clean_range)
+		outer_cache.clean_range(start, end);
+}
+static inline void outer_flush_range(unsigned long start, unsigned long end)
+{
+	if (outer_cache.flush_range)
+		outer_cache.flush_range(start, end);
+}
+
+#else
+
+static inline void outer_inv_range(unsigned long start, unsigned long end)
+{ }
+static inline void outer_clean_range(unsigned long start, unsigned long end)
+{ }
+static inline void outer_flush_range(unsigned long start, unsigned long end)
+{ }
 
 #endif
 
diff --git a/include/asm-arm/checksum.h b/include/asm-arm/checksum.h
index 8c0bb5b..eaa0efd 100644
--- a/include/asm-arm/checksum.h
+++ b/include/asm-arm/checksum.h
@@ -40,13 +40,27 @@
 csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr);
 
 /*
+ * 	Fold a partial checksum without adding pseudo headers
+ */
+static inline __sum16 csum_fold(__wsum sum)
+{
+	__asm__(
+	"add	%0, %1, %1, ror #16	@ csum_fold"
+	: "=r" (sum)
+	: "r" (sum)
+	: "cc");
+	return (__force __sum16)(~(__force u32)sum >> 16);
+}
+
+/*
  *	This is a version of ip_compute_csum() optimized for IP headers,
  *	which always checksum on 4 octet boundaries.
  */
 static inline __sum16
 ip_fast_csum(const void *iph, unsigned int ihl)
 {
-	unsigned int sum, tmp1;
+	unsigned int tmp1;
+	__wsum sum;
 
 	__asm__ __volatile__(
 	"ldr	%0, [%1], #4		@ ip_fast_csum		\n\
@@ -62,29 +76,11 @@
 	subne	%2, %2, #1		@ without destroying	\n\
 	bne	1b			@ the carry flag	\n\
 	adcs	%0, %0, %3					\n\
-	adc	%0, %0, #0					\n\
-	adds	%0, %0, %0, lsl #16				\n\
-	addcs	%0, %0, #0x10000				\n\
-	mvn	%0, %0						\n\
-	mov	%0, %0, lsr #16"
+	adc	%0, %0, #0"
 	: "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1)
 	: "1" (iph), "2" (ihl)
 	: "cc", "memory");
-	return (__force __sum16)sum;
-}
-
-/*
- * 	Fold a partial checksum without adding pseudo headers
- */
-static inline __sum16 csum_fold(__wsum sum)
-{
-	__asm__(
-	"adds	%0, %1, %1, lsl #16	@ csum_fold		\n\
-	addcs	%0, %0, #0x10000"
-	: "=r" (sum)
-	: "r" (sum)
-	: "cc");
-	return (__force __sum16)(~(__force u32)sum >> 16);
+	return csum_fold(sum);
 }
 
 static inline __wsum
@@ -114,23 +110,7 @@
 csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
 		  unsigned short proto, __wsum sum)
 {
-	__asm__(
-	"adds	%0, %1, %2		@ csum_tcpudp_magic	\n\
-	adcs	%0, %0, %3					\n"
-#ifdef __ARMEB__
-	"adcs	%0, %0, %4					\n"
-#else
-	"adcs	%0, %0, %4, lsl #8				\n"
-#endif
-	"adcs	%0, %0, %5					\n\
-	adc	%0, %0, #0					\n\
-	adds	%0, %0, %0, lsl #16				\n\
-	addcs	%0, %0, #0x10000				\n\
-	mvn	%0, %0"
-	: "=&r"(sum)
-	: "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (htons(proto))
-	: "cc");
-	return (__force __sum16)((__force u32)sum >> 16);
+	return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
 }
 
 
diff --git a/include/asm-arm/device.h b/include/asm-arm/device.h
index d8f9872..c61642b 100644
--- a/include/asm-arm/device.h
+++ b/include/asm-arm/device.h
@@ -3,5 +3,13 @@
  *
  * This file is released under the GPLv2
  */
-#include <asm-generic/device.h>
+#ifndef ASMARM_DEVICE_H
+#define ASMARM_DEVICE_H
 
+struct dev_archdata {
+#ifdef CONFIG_DMABOUNCE
+	struct dmabounce_device_info *dmabounce;
+#endif
+};
+
+#endif
diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
index 9bc46b4..abfb75b 100644
--- a/include/asm-arm/dma-mapping.h
+++ b/include/asm-arm/dma-mapping.h
@@ -17,7 +17,7 @@
  * platforms with CONFIG_DMABOUNCE.
  * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
  */
-extern void consistent_sync(void *kaddr, size_t size, int rw);
+extern void consistent_sync(const void *kaddr, size_t size, int rw);
 
 /*
  * Return whether the given device DMA address mask can be supported
@@ -61,6 +61,22 @@
 	return dma_addr == ~0;
 }
 
+/*
+ * Dummy noncoherent implementation.  We don't provide a dma_cache_sync
+ * function so drivers using this API are highlighted with build warnings.
+ */
+static inline void *
+dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+{
+	return NULL;
+}
+
+static inline void
+dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr,
+		     dma_addr_t handle)
+{
+}
+
 /**
  * dma_alloc_coherent - allocate consistent memory for DMA
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
diff --git a/include/asm-arm/domain.h b/include/asm-arm/domain.h
index 4c2885a..3c12a76 100644
--- a/include/asm-arm/domain.h
+++ b/include/asm-arm/domain.h
@@ -57,6 +57,7 @@
 	__asm__ __volatile__(				\
 	"mcr	p15, 0, %0, c3, c0	@ set domain"	\
 	  : : "r" (x));					\
+	isb();						\
 	} while (0)
 
 #define modify_domain(dom,type)					\
diff --git a/include/asm-arm/hardware/arm_scu.h b/include/asm-arm/hardware/arm_scu.h
index 9903f60..7d28eb5 100644
--- a/include/asm-arm/hardware/arm_scu.h
+++ b/include/asm-arm/hardware/arm_scu.h
@@ -1,6 +1,8 @@
 #ifndef ASMARM_HARDWARE_ARM_SCU_H
 #define ASMARM_HARDWARE_ARM_SCU_H
 
+#include <asm/arch/scu.h>
+
 /*
  * SCU registers
  */
diff --git a/include/asm-arm/hardware/cache-l2x0.h b/include/asm-arm/hardware/cache-l2x0.h
new file mode 100644
index 0000000..54029a7
--- /dev/null
+++ b/include/asm-arm/hardware/cache-l2x0.h
@@ -0,0 +1,56 @@
+/*
+ * include/asm-arm/hardware/cache-l2x0.h
+ *
+ * Copyright (C) 2007 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#ifndef __ASM_ARM_HARDWARE_L2X0_H
+#define __ASM_ARM_HARDWARE_L2X0_H
+
+#define L2X0_CACHE_ID			0x000
+#define L2X0_CACHE_TYPE			0x004
+#define L2X0_CTRL			0x100
+#define L2X0_AUX_CTRL			0x104
+#define L2X0_EVENT_CNT_CTRL		0x200
+#define L2X0_EVENT_CNT1_CFG		0x204
+#define L2X0_EVENT_CNT0_CFG		0x208
+#define L2X0_EVENT_CNT1_VAL		0x20C
+#define L2X0_EVENT_CNT0_VAL		0x210
+#define L2X0_INTR_MASK			0x214
+#define L2X0_MASKED_INTR_STAT		0x218
+#define L2X0_RAW_INTR_STAT		0x21C
+#define L2X0_INTR_CLEAR			0x220
+#define L2X0_CACHE_SYNC			0x730
+#define L2X0_INV_LINE_PA		0x770
+#define L2X0_INV_WAY			0x77C
+#define L2X0_CLEAN_LINE_PA		0x7B0
+#define L2X0_CLEAN_LINE_IDX		0x7B8
+#define L2X0_CLEAN_WAY			0x7BC
+#define L2X0_CLEAN_INV_LINE_PA		0x7F0
+#define L2X0_CLEAN_INV_LINE_IDX		0x7F8
+#define L2X0_CLEAN_INV_WAY		0x7FC
+#define L2X0_LOCKDOWN_WAY_D		0x900
+#define L2X0_LOCKDOWN_WAY_I		0x904
+#define L2X0_TEST_OPERATION		0xF00
+#define L2X0_LINE_DATA			0xF10
+#define L2X0_LINE_TAG			0xF30
+#define L2X0_DEBUG_CTRL			0xF40
+
+#ifndef __ASSEMBLY__
+extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
+#endif
+
+#endif
diff --git a/include/asm-arm/hardware/gic.h b/include/asm-arm/hardware/gic.h
index 3fa5eb7..966e428 100644
--- a/include/asm-arm/hardware/gic.h
+++ b/include/asm-arm/hardware/gic.h
@@ -33,8 +33,9 @@
 #define GIC_DIST_SOFTINT		0xf00
 
 #ifndef __ASSEMBLY__
-void gic_dist_init(void __iomem *base);
-void gic_cpu_init(void __iomem *base);
+void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start);
+void gic_cpu_init(unsigned int gic_nr, void __iomem *base);
+void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
 void gic_raise_softirq(cpumask_t cpumask, unsigned int irq);
 #endif
 
diff --git a/include/asm-arm/hardware/iop3xx.h b/include/asm-arm/hardware/iop3xx.h
index 13ac8a4..c91b546 100644
--- a/include/asm-arm/hardware/iop3xx.h
+++ b/include/asm-arm/hardware/iop3xx.h
@@ -37,6 +37,13 @@
 #define IOP3XX_PERIPHERAL_PHYS_BASE	0xffffe000
 #define IOP3XX_PERIPHERAL_VIRT_BASE	0xfeffe000
 #define IOP3XX_PERIPHERAL_SIZE		0x00002000
+#define IOP3XX_PERIPHERAL_UPPER_PA (IOP3XX_PERIPHERAL_PHYS_BASE +\
+					IOP3XX_PERIPHERAL_SIZE - 1)
+#define IOP3XX_PERIPHERAL_UPPER_VA (IOP3XX_PERIPHERAL_VIRT_BASE +\
+					IOP3XX_PERIPHERAL_SIZE - 1)
+#define IOP3XX_PMMR_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
+					(IOP3XX_PERIPHERAL_PHYS_BASE\
+					- IOP3XX_PERIPHERAL_VIRT_BASE))
 #define IOP3XX_REG_ADDR(reg)		(IOP3XX_PERIPHERAL_VIRT_BASE + (reg))
 
 /* Address Translation Unit  */
@@ -258,12 +265,20 @@
 #define IOP3XX_PCI_LOWER_IO_PA		0x90000000
 #define IOP3XX_PCI_LOWER_IO_VA		0xfe000000
 #define IOP3XX_PCI_LOWER_IO_BA		(*IOP3XX_OIOWTVR)
+#define IOP3XX_PCI_UPPER_IO_PA		(IOP3XX_PCI_LOWER_IO_PA +\
+					IOP3XX_PCI_IO_WINDOW_SIZE - 1)
+#define IOP3XX_PCI_UPPER_IO_VA		(IOP3XX_PCI_LOWER_IO_VA +\
+					IOP3XX_PCI_IO_WINDOW_SIZE - 1)
+#define IOP3XX_PCI_IO_PHYS_TO_VIRT(addr) (((u32) addr -\
+					IOP3XX_PCI_LOWER_IO_PA) +\
+					IOP3XX_PCI_LOWER_IO_VA)
 
 
 #ifndef __ASSEMBLY__
 void iop3xx_map_io(void);
 void iop3xx_init_time(unsigned long);
 unsigned long iop3xx_gettimeoffset(void);
+void iop_init_cp6_handler(void);
 
 extern struct platform_device iop3xx_i2c0_device;
 extern struct platform_device iop3xx_i2c1_device;
diff --git a/include/asm-arm/hardware/sa1111.h b/include/asm-arm/hardware/sa1111.h
index 6aa0a5b..61b1d05 100644
--- a/include/asm-arm/hardware/sa1111.h
+++ b/include/asm-arm/hardware/sa1111.h
@@ -29,6 +29,9 @@
 #define _SA1111(x)	((x) + sa1111->resource.start)
 #endif
 
+#define sa1111_writel(val,addr)	__raw_writel(val, addr)
+#define sa1111_readl(addr)	__raw_readl(addr)
+
 /*
  * 26 bits of the SA-1110 address bus are available to the SA-1111.
  * Use these when feeding target addresses to the DMA engines.
@@ -45,14 +48,6 @@
 #define SA1111_SAC_DMA_MIN_XFER	(0x800)
 
 /*
- * SA1111 register definitions.
- */
-#define __CCREG(x)	__REGP(SA1111_VBASE + (x))
-
-#define sa1111_writel(val,addr)	__raw_writel(val, addr)
-#define sa1111_readl(addr)	__raw_readl(addr)
-
-/*
  * System Bus Interface (SBI)
  *
  * Registers
@@ -194,55 +189,37 @@
  *    SADR              Serial Audio Data Register (16 x 32-bit)
  */
 
-#define _SACR0          _SA1111( 0x0600 )
-#define _SACR1          _SA1111( 0x0604 )
-#define _SACR2          _SA1111( 0x0608 )
-#define _SASR0          _SA1111( 0x060c )
-#define _SASR1          _SA1111( 0x0610 )
-#define _SASCR          _SA1111( 0x0618 )
-#define _L3_CAR         _SA1111( 0x061c )
-#define _L3_CDR         _SA1111( 0x0620 )
-#define _ACCAR          _SA1111( 0x0624 )
-#define _ACCDR          _SA1111( 0x0628 )
-#define _ACSAR          _SA1111( 0x062c )
-#define _ACSDR          _SA1111( 0x0630 )
-#define _SADTCS         _SA1111( 0x0634 )
-#define _SADTSA         _SA1111( 0x0638 )
-#define _SADTCA         _SA1111( 0x063c )
-#define _SADTSB         _SA1111( 0x0640 )
-#define _SADTCB         _SA1111( 0x0644 )
-#define _SADRCS         _SA1111( 0x0648 )
-#define _SADRSA         _SA1111( 0x064c )
-#define _SADRCA         _SA1111( 0x0650 )
-#define _SADRSB         _SA1111( 0x0654 )
-#define _SADRCB         _SA1111( 0x0658 )
-#define _SAITR          _SA1111( 0x065c )
-#define _SADR           _SA1111( 0x0680 )
+#define SA1111_SERAUDIO		0x0600
 
-#define SACR0		__CCREG(0x0600)
-#define SACR1		__CCREG(0x0604)
-#define SACR2		__CCREG(0x0608)
-#define SASR0		__CCREG(0x060c)
-#define SASR1		__CCREG(0x0610)
-#define SASCR		__CCREG(0x0618)
-#define L3_CAR		__CCREG(0x061c)
-#define L3_CDR		__CCREG(0x0620)
-#define ACCAR		__CCREG(0x0624)
-#define ACCDR		__CCREG(0x0628)
-#define ACSAR		__CCREG(0x062c)
-#define ACSDR		__CCREG(0x0630)
-#define SADTCS		__CCREG(0x0634)
-#define SADTSA		__CCREG(0x0638)
-#define SADTCA		__CCREG(0x063c)
-#define SADTSB		__CCREG(0x0640)
-#define SADTCB		__CCREG(0x0644)
-#define SADRCS		__CCREG(0x0648)
-#define SADRSA		__CCREG(0x064c)
-#define SADRCA		__CCREG(0x0650)
-#define SADRSB		__CCREG(0x0654)
-#define SADRCB		__CCREG(0x0658)
-#define SAITR		__CCREG(0x065c)
-#define SADR		__CCREG(0x0680)
+/*
+ * These are offsets from the above base.
+ */
+#define SA1111_SACR0		0x00
+#define SA1111_SACR1		0x04
+#define SA1111_SACR2		0x08
+#define SA1111_SASR0		0x0c
+#define SA1111_SASR1		0x10
+#define SA1111_SASCR		0x18
+#define SA1111_L3_CAR		0x1c
+#define SA1111_L3_CDR		0x20
+#define SA1111_ACCAR		0x24
+#define SA1111_ACCDR		0x28
+#define SA1111_ACSAR		0x2c
+#define SA1111_ACSDR		0x30
+#define SA1111_SADTCS		0x34
+#define SA1111_SADTSA		0x38
+#define SA1111_SADTCA		0x3c
+#define SA1111_SADTSB		0x40
+#define SA1111_SADTCB		0x44
+#define SA1111_SADRCS		0x48
+#define SA1111_SADRSA		0x4c
+#define SA1111_SADRCA		0x50
+#define SA1111_SADRSB		0x54
+#define SA1111_SADRCB		0x58
+#define SA1111_SAITR		0x5c
+#define SA1111_SADR		0x80
+
+#ifndef CONFIG_ARCH_PXA
 
 #define SACR0_ENB	(1<<0)
 #define SACR0_BCKD	(1<<2)
@@ -330,6 +307,8 @@
 #define SAITR_RDBDA	(1<<10)
 #define SAITR_RDBDB	(1<<11)
 
+#endif  /* !CONFIG_ARCH_PXA */
+
 /*
  * General-Purpose I/O Interface
  *
diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h
new file mode 100644
index 0000000..8c1c616
--- /dev/null
+++ b/include/asm-arm/kexec.h
@@ -0,0 +1,30 @@
+#ifndef _ARM_KEXEC_H
+#define _ARM_KEXEC_H
+
+#ifdef CONFIG_KEXEC
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+/* Maximum address we can use for the control code buffer */
+#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
+
+#define KEXEC_CONTROL_CODE_SIZE	4096
+
+#define KEXEC_ARCH KEXEC_ARCH_ARM
+
+#ifndef __ASSEMBLY__
+
+#define MAX_NOTE_BYTES 1024
+
+struct kimage;
+/* Provide a dummy definition to avoid build failures. */
+static inline void crash_setup_regs(struct pt_regs *newregs,
+                                        struct pt_regs *oldregs) { }
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_KEXEC */
+
+#endif /* _ARM_KEXEC_H */
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index b8cf2d5..7b2bafc 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -175,19 +175,29 @@
 #ifndef __ASSEMBLY__
 
 /*
- * The following macros handle the cache and bufferable bits...
+ * The pgprot_* and protection_map entries will be fixed up in runtime
+ * to include the cachable and bufferable bits based on memory policy,
+ * as well as any architecture dependent bits like global/ASID and SMP
+ * shared mapping bits.
  */
 #define _L_PTE_DEFAULT	L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_CACHEABLE | L_PTE_BUFFERABLE
 #define _L_PTE_READ	L_PTE_USER | L_PTE_EXEC
 
+extern pgprot_t		pgprot_user;
 extern pgprot_t		pgprot_kernel;
 
-#define PAGE_NONE       __pgprot(_L_PTE_DEFAULT)
-#define PAGE_COPY       __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
-#define PAGE_SHARED     __pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE)
-#define PAGE_READONLY   __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
+#define PAGE_NONE	pgprot_user
+#define PAGE_COPY	__pgprot(pgprot_val(pgprot_user) | _L_PTE_READ)
+#define PAGE_SHARED	__pgprot(pgprot_val(pgprot_user) | _L_PTE_READ | \
+				 L_PTE_WRITE)
+#define PAGE_READONLY	__pgprot(pgprot_val(pgprot_user) | _L_PTE_READ)
 #define PAGE_KERNEL	pgprot_kernel
 
+#define __PAGE_NONE	__pgprot(_L_PTE_DEFAULT)
+#define __PAGE_COPY	__pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
+#define __PAGE_SHARED	__pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE)
+#define __PAGE_READONLY	__pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
+
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -198,23 +208,23 @@
  *  2) If we could do execute protection, then read is implied
  *  3) write implies read permissions
  */
-#define __P000  PAGE_NONE
-#define __P001  PAGE_READONLY
-#define __P010  PAGE_COPY
-#define __P011  PAGE_COPY
-#define __P100  PAGE_READONLY
-#define __P101  PAGE_READONLY
-#define __P110  PAGE_COPY
-#define __P111  PAGE_COPY
+#define __P000  __PAGE_NONE
+#define __P001  __PAGE_READONLY
+#define __P010  __PAGE_COPY
+#define __P011  __PAGE_COPY
+#define __P100  __PAGE_READONLY
+#define __P101  __PAGE_READONLY
+#define __P110  __PAGE_COPY
+#define __P111  __PAGE_COPY
 
-#define __S000  PAGE_NONE
-#define __S001  PAGE_READONLY
-#define __S010  PAGE_SHARED
-#define __S011  PAGE_SHARED
-#define __S100  PAGE_READONLY
-#define __S101  PAGE_READONLY
-#define __S110  PAGE_SHARED
-#define __S111  PAGE_SHARED
+#define __S000  __PAGE_NONE
+#define __S001  __PAGE_READONLY
+#define __S010  __PAGE_SHARED
+#define __S011  __PAGE_SHARED
+#define __S100  __PAGE_READONLY
+#define __S101  __PAGE_READONLY
+#define __S110  __PAGE_SHARED
+#define __S111  __PAGE_SHARED
 
 #ifndef __ASSEMBLY__
 /*
diff --git a/arch/arm/mach-s3c2410/clock.h b/include/asm-arm/plat-s3c24xx/clock.h
similarity index 96%
rename from arch/arm/mach-s3c2410/clock.h
rename to include/asm-arm/plat-s3c24xx/clock.h
index 7f0ea03..f6135db 100644
--- a/arch/arm/mach-s3c2410/clock.h
+++ b/include/asm-arm/plat-s3c24xx/clock.h
@@ -1,4 +1,4 @@
-/*
+/* linux/include/asm-arm/plat-s3c24xx/clock.h
  * linux/arch/arm/mach-s3c2410/clock.h
  *
  * Copyright (c) 2004-2005 Simtec Electronics
diff --git a/arch/arm/mach-s3c2410/common-smdk.h b/include/asm-arm/plat-s3c24xx/common-smdk.h
similarity index 88%
rename from arch/arm/mach-s3c2410/common-smdk.h
rename to include/asm-arm/plat-s3c24xx/common-smdk.h
index 0e3a3be..58d9094 100644
--- a/arch/arm/mach-s3c2410/common-smdk.h
+++ b/include/asm-arm/plat-s3c24xx/common-smdk.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/common-smdk.h
+/* linux/include/asm-arm/plat-s3c24xx/common-smdk.h
  *
  * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/cpu.h b/include/asm-arm/plat-s3c24xx/cpu.h
similarity index 94%
rename from arch/arm/mach-s3c2410/cpu.h
rename to include/asm-arm/plat-s3c24xx/cpu.h
index be42e40..15dd188 100644
--- a/arch/arm/mach-s3c2410/cpu.h
+++ b/include/asm-arm/plat-s3c24xx/cpu.h
@@ -1,4 +1,4 @@
-/* arch/arm/mach-s3c2410/cpu.h
+/* linux/include/asm-arm/plat-s3c24xx/cpu.h
  *
  * Copyright (c) 2004-2005 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
@@ -67,3 +67,4 @@
 extern struct sysdev_class s3c2412_sysclass;
 extern struct sysdev_class s3c2440_sysclass;
 extern struct sysdev_class s3c2442_sysclass;
+extern struct sysdev_class s3c2443_sysclass;
diff --git a/arch/arm/mach-s3c2410/devs.h b/include/asm-arm/plat-s3c24xx/devs.h
similarity index 96%
rename from arch/arm/mach-s3c2410/devs.h
rename to include/asm-arm/plat-s3c24xx/devs.h
index 14fb0ba..dddf485 100644
--- a/arch/arm/mach-s3c2410/devs.h
+++ b/include/asm-arm/plat-s3c24xx/devs.h
@@ -1,4 +1,4 @@
-/* arch/arm/mach-s3c2410/devs.h
+/* linux/include/asm-arm/plat-s3c24xx/devs.h
  *
  * Copyright (c) 2004 Simtec Electronics
  * Ben Dooks <ben@simtec.co.uk>
diff --git a/include/asm-arm/plat-s3c24xx/dma.h b/include/asm-arm/plat-s3c24xx/dma.h
new file mode 100644
index 0000000..2c59406
--- /dev/null
+++ b/include/asm-arm/plat-s3c24xx/dma.h
@@ -0,0 +1,77 @@
+/* linux/include/asm-arm/plat-s3c24xx/dma.h
+ *
+ * Copyright (C) 2006 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C24XX DMA support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+extern struct sysdev_class dma_sysclass;
+extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
+
+#define DMA_CH_VALID		(1<<31)
+#define DMA_CH_NEVER		(1<<30)
+
+struct s3c24xx_dma_addr {
+	unsigned long		from;
+	unsigned long		to;
+};
+
+/* struct s3c24xx_dma_map
+ *
+ * this holds the mapping information for the channel selected
+ * to be connected to the specified device
+*/
+
+struct s3c24xx_dma_map {
+	const char		*name;
+	struct s3c24xx_dma_addr  hw_addr;
+
+	unsigned long		 channels[S3C2410_DMA_CHANNELS];
+};
+
+struct s3c24xx_dma_selection {
+	struct s3c24xx_dma_map	*map;
+	unsigned long		 map_size;
+	unsigned long		 dcon_mask;
+
+	void	(*select)(struct s3c2410_dma_chan *chan,
+			  struct s3c24xx_dma_map *map);
+};
+
+extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
+
+/* struct s3c24xx_dma_order_ch
+ *
+ * channel map for one of the `enum dma_ch` dma channels. the list
+ * entry contains a set of low-level channel numbers, orred with
+ * DMA_CH_VALID, which are checked in the order in the array.
+*/
+
+struct s3c24xx_dma_order_ch {
+	unsigned int	list[S3C2410_DMA_CHANNELS];	/* list of channels */
+	unsigned int	flags;				/* flags */
+};
+
+/* struct s3c24xx_dma_order
+ *
+ * information provided by either the core or the board to give the
+ * dma system a hint on how to allocate channels
+*/
+
+struct s3c24xx_dma_order {
+	struct s3c24xx_dma_order_ch	channels[DMACH_MAX];
+};
+
+extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
+
+/* DMA init code, called from the cpu support code */
+
+extern int s3c2410_dma_init(void);
+
+extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq,
+			    unsigned int stride);
diff --git a/arch/arm/mach-s3c2410/irq.h b/include/asm-arm/plat-s3c24xx/irq.h
similarity index 97%
rename from arch/arm/mach-s3c2410/irq.h
rename to include/asm-arm/plat-s3c24xx/irq.h
index e5913da..8af6d95 100644
--- a/arch/arm/mach-s3c2410/irq.h
+++ b/include/asm-arm/plat-s3c24xx/irq.h
@@ -1,4 +1,4 @@
-/* arch/arm/mach-s3c2410/irq.h
+/* linux/include/asm-arm/plat-s3c24xx/irq.h
  *
  * Copyright (c) 2004-2005 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/pm.h b/include/asm-arm/plat-s3c24xx/pm.h
similarity index 96%
rename from arch/arm/mach-s3c2410/pm.h
rename to include/asm-arm/plat-s3c24xx/pm.h
index ffe197a..cc62366 100644
--- a/arch/arm/mach-s3c2410/pm.h
+++ b/include/asm-arm/plat-s3c24xx/pm.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/pm.h
+/* linux/include/asm-arm/plat-s3c24xx/pm.h
  *
  * Copyright (c) 2004 Simtec Electronics
  *	Written by Ben Dooks, <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/s3c2400.h b/include/asm-arm/plat-s3c24xx/s3c2400.h
similarity index 93%
rename from arch/arm/mach-s3c2410/s3c2400.h
rename to include/asm-arm/plat-s3c24xx/s3c2400.h
index 8b2394e..3a5a168 100644
--- a/arch/arm/mach-s3c2410/s3c2400.h
+++ b/include/asm-arm/plat-s3c24xx/s3c2400.h
@@ -1,4 +1,4 @@
-/* arch/arm/mach-s3c2410/s3c2400.h
+/* linux/include/asm-arm/plat-s3c24xx/s3c2400.h
  *
  * Copyright (c) 2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/s3c2410.h b/include/asm-arm/plat-s3c24xx/s3c2410.h
similarity index 93%
rename from arch/arm/mach-s3c2410/s3c2410.h
rename to include/asm-arm/plat-s3c24xx/s3c2410.h
index fbed084..36de0b8 100644
--- a/arch/arm/mach-s3c2410/s3c2410.h
+++ b/include/asm-arm/plat-s3c24xx/s3c2410.h
@@ -1,4 +1,4 @@
-/* arch/arm/mach-s3c2410/s3c2410.h
+/* linux/include/asm-arm/plat-s3c24xx/s3c2410.h
  *
  * Copyright (c) 2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/s3c2412.h b/include/asm-arm/plat-s3c24xx/s3c2412.h
similarity index 93%
rename from arch/arm/mach-s3c2410/s3c2412.h
rename to include/asm-arm/plat-s3c24xx/s3c2412.h
index c6e5603..3ec9768 100644
--- a/arch/arm/mach-s3c2410/s3c2412.h
+++ b/include/asm-arm/plat-s3c24xx/s3c2412.h
@@ -1,4 +1,4 @@
-/* arch/arm/mach-s3c2410/s3c2412.h
+/* linux/include/asm-arm/plat-s3c24xx/s3c2412.h
  *
  * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/s3c2440.h b/include/asm-arm/plat-s3c24xx/s3c2440.h
similarity index 89%
rename from arch/arm/mach-s3c2410/s3c2440.h
rename to include/asm-arm/plat-s3c24xx/s3c2440.h
index dcd3160..107853b 100644
--- a/arch/arm/mach-s3c2410/s3c2440.h
+++ b/include/asm-arm/plat-s3c24xx/s3c2440.h
@@ -1,4 +1,4 @@
-/* arch/arm/mach-s3c2410/s3c2440.h
+/* linux/include/asm-arm/plat-s3c24xx/s3c2440.h
  *
  * Copyright (c) 2004-2005 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/s3c2442.h b/include/asm-arm/plat-s3c24xx/s3c2442.h
similarity index 89%
rename from arch/arm/mach-s3c2410/s3c2442.h
rename to include/asm-arm/plat-s3c24xx/s3c2442.h
index 0ae37d2..451a23a 100644
--- a/arch/arm/mach-s3c2410/s3c2442.h
+++ b/include/asm-arm/plat-s3c24xx/s3c2442.h
@@ -1,4 +1,4 @@
-/* arch/arm/mach-s3c2410/s3c2442.h
+/* linux/include/asm-arm/plat-s3c24xx/s3c2442.h
  *
  * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/include/asm-arm/plat-s3c24xx/s3c2443.h b/include/asm-arm/plat-s3c24xx/s3c2443.h
new file mode 100644
index 0000000..11d83b5
--- /dev/null
+++ b/include/asm-arm/plat-s3c24xx/s3c2443.h
@@ -0,0 +1,32 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2443 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifdef CONFIG_CPU_S3C2443
+
+struct s3c2410_uartcfg;
+
+extern  int s3c2443_init(void);
+
+extern void s3c2443_map_io(struct map_desc *mach_desc, int size);
+
+extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2443_init_clocks(int xtal);
+
+extern  int s3c2443_baseclk_add(void);
+
+#else
+#define s3c2443_init_clocks NULL
+#define s3c2443_init_uarts NULL
+#define s3c2443_map_io NULL
+#define s3c2443_init NULL
+#endif
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index aa223fc..f438690 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -140,6 +140,40 @@
 #define	cpu_is_xscale()	1
 #endif
 
+#define UDBG_UNDEFINED	(1 << 0)
+#define UDBG_SYSCALL	(1 << 1)
+#define UDBG_BADABORT	(1 << 2)
+#define UDBG_SEGV	(1 << 3)
+#define UDBG_BUS	(1 << 4)
+
+extern unsigned int user_debug;
+
+#if __LINUX_ARM_ARCH__ >= 4
+#define vectors_high()	(cr_alignment & CR_V)
+#else
+#define vectors_high()	(0)
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 6
+#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
+				    : : "r" (0) : "memory")
+#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
+				    : : "r" (0) : "memory")
+#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
+				    : : "r" (0) : "memory")
+#else
+#define isb() __asm__ __volatile__ ("" : : : "memory")
+#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
+				    : : "r" (0) : "memory")
+#define dmb() __asm__ __volatile__ ("" : : : "memory")
+#endif
+#define mb() dmb()
+#define rmb() mb()
+#define wmb() mb()
+#define read_barrier_depends() do { } while(0)
+#define set_mb(var, value)  do { var = value; mb(); } while (0)
+#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
+
 extern unsigned long cr_no_alignment;	/* defined in entry-armv.S */
 extern unsigned long cr_alignment;	/* defined in entry-armv.S */
 
@@ -154,6 +188,7 @@
 {
 	asm volatile("mcr p15, 0, %0, c1, c0, 0	@ set CR"
 	  : : "r" (val) : "cc");
+	isb();
 }
 
 #ifndef CONFIG_SMP
@@ -176,34 +211,9 @@
 {
 	asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access"
 	  : : "r" (val) : "cc");
+	isb();
 }
 
-#define UDBG_UNDEFINED	(1 << 0)
-#define UDBG_SYSCALL	(1 << 1)
-#define UDBG_BADABORT	(1 << 2)
-#define UDBG_SEGV	(1 << 3)
-#define UDBG_BUS	(1 << 4)
-
-extern unsigned int user_debug;
-
-#if __LINUX_ARM_ARCH__ >= 4
-#define vectors_high()	(cr_alignment & CR_V)
-#else
-#define vectors_high()	(0)
-#endif
-
-#if __LINUX_ARM_ARCH__ >= 6
-#define mb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
-                                   : : "r" (0) : "memory")
-#else
-#define mb() __asm__ __volatile__ ("" : : : "memory")
-#endif
-#define rmb() mb()
-#define wmb() mb()
-#define read_barrier_depends() do { } while(0)
-#define set_mb(var, value)  do { var = value; mb(); } while (0)
-#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
-
 /*
  * switch_mm() may do a full cache flush over the context switch,
  * so enable interrupts over the context switch to avoid high
diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h
index cd10a0b..08c6991 100644
--- a/include/asm-arm/tlbflush.h
+++ b/include/asm-arm/tlbflush.h
@@ -247,7 +247,7 @@
 	const unsigned int __tlb_flag = __cpu_tlb_flags;
 
 	if (tlb_flag(TLB_WB))
-		asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
+		dsb();
 
 	if (tlb_flag(TLB_V3_FULL))
 		asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
@@ -257,6 +257,15 @@
 		asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
 	if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL))
 		asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
+
+	if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
+		     TLB_V6_I_PAGE | TLB_V6_D_PAGE |
+		     TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+		/* flush the branch target cache */
+		asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+		dsb();
+		isb();
+	}
 }
 
 static inline void local_flush_tlb_mm(struct mm_struct *mm)
@@ -266,7 +275,7 @@
 	const unsigned int __tlb_flag = __cpu_tlb_flags;
 
 	if (tlb_flag(TLB_WB))
-		asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
+		dsb();
 
 	if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) {
 		if (tlb_flag(TLB_V3_FULL))
@@ -285,6 +294,14 @@
 		asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc");
 	if (tlb_flag(TLB_V6_I_ASID))
 		asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc");
+
+	if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
+		     TLB_V6_I_PAGE | TLB_V6_D_PAGE |
+		     TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+		/* flush the branch target cache */
+		asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+		dsb();
+	}
 }
 
 static inline void
@@ -296,7 +313,7 @@
 	uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm);
 
 	if (tlb_flag(TLB_WB))
-		asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero));
+		dsb();
 
 	if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) {
 		if (tlb_flag(TLB_V3_PAGE))
@@ -317,6 +334,14 @@
 		asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
 	if (tlb_flag(TLB_V6_I_PAGE))
 		asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
+
+	if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
+		     TLB_V6_I_PAGE | TLB_V6_D_PAGE |
+		     TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+		/* flush the branch target cache */
+		asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+		dsb();
+	}
 }
 
 static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
@@ -327,7 +352,7 @@
 	kaddr &= PAGE_MASK;
 
 	if (tlb_flag(TLB_WB))
-		asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
+		dsb();
 
 	if (tlb_flag(TLB_V3_PAGE))
 		asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc");
@@ -347,11 +372,14 @@
 	if (tlb_flag(TLB_V6_I_PAGE))
 		asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
 
-	/* The ARM ARM states that the completion of a TLB maintenance
-	 * operation is only guaranteed by a DSB instruction
-	 */
-	if (tlb_flag(TLB_V6_U_PAGE | TLB_V6_D_PAGE | TLB_V6_I_PAGE))
-		asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
+	if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
+		     TLB_V6_I_PAGE | TLB_V6_D_PAGE |
+		     TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+		/* flush the branch target cache */
+		asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+		dsb();
+		isb();
+	}
 }
 
 /*
@@ -369,15 +397,13 @@
  */
 static inline void flush_pmd_entry(pmd_t *pmd)
 {
-	const unsigned int zero = 0;
 	const unsigned int __tlb_flag = __cpu_tlb_flags;
 
 	if (tlb_flag(TLB_DCLEAN))
 		asm("mcr	p15, 0, %0, c7, c10, 1	@ flush_pmd"
 			: : "r" (pmd) : "cc");
 	if (tlb_flag(TLB_WB))
-		asm("mcr	p15, 0, %0, c7, c10, 4	@ flush_pmd"
-			: : "r" (zero) : "cc");
+		dsb();
 }
 
 static inline void clean_pmd_entry(pmd_t *pmd)
diff --git a/include/asm-arm/uaccess.h b/include/asm-arm/uaccess.h
index c92df95..4c1a3fa 100644
--- a/include/asm-arm/uaccess.h
+++ b/include/asm-arm/uaccess.h
@@ -109,7 +109,7 @@
 
 #define get_user(x,p)							\
 	({								\
-		const register typeof(*(p)) __user *__p asm("r0") = (p);\
+		register const typeof(*(p)) __user *__p asm("r0") = (p);\
 		register unsigned long __r2 asm("r2");			\
 		register int __e asm("r0");				\
 		switch (sizeof(*(__p))) {				\
@@ -143,8 +143,8 @@
 
 #define put_user(x,p)							\
 	({								\
-		const register typeof(*(p)) __r2 asm("r2") = (x);	\
-		const register typeof(*(p)) __user *__p asm("r0") = (p);\
+		register const typeof(*(p)) __r2 asm("r2") = (x);	\
+		register const typeof(*(p)) __user *__p asm("r0") = (p);\
 		register int __e asm("r0");				\
 		switch (sizeof(*(__p))) {				\
 		case 1:							\
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index 97e7060..0991b7b 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -372,6 +372,7 @@
 #define __NR_move_pages			(__NR_SYSCALL_BASE+344)
 #define __NR_getcpu			(__NR_SYSCALL_BASE+345)
 					/* 346 for epoll_pwait */
+#define __NR_sys_kexec_load		(__NR_SYSCALL_BASE+347)
 
 /*
  * The following SWIs are ARM private.
diff --git a/include/asm-arm26/uaccess.h b/include/asm-arm26/uaccess.h
index 3f2dd10..d64ed84 100644
--- a/include/asm-arm26/uaccess.h
+++ b/include/asm-arm26/uaccess.h
@@ -74,7 +74,7 @@
 
 #define get_user(x,p)							\
 	({								\
-		const register typeof(*(p)) *__p asm("r0") = (p);	\
+		register const typeof(*(p)) *__p asm("r0") = (p);	\
 		register typeof(*(p)) __r1 asm("r1");			\
 		register int __e asm("r0");				\
 		switch (sizeof(*(p))) {					\
@@ -139,8 +139,8 @@
 
 #define put_user(x,p)                                                   \
         ({                                                              \
-                const register typeof(*(p)) __r1 asm("r1") = (x);       \
-                const register typeof(*(p)) *__p asm("r0") = (p);       \
+                register const typeof(*(p)) __r1 asm("r1") = (x);       \
+                register const typeof(*(p)) *__p asm("r0") = (p);       \
                 register int __e asm("r0");                             \
                 switch (sizeof(*(__p))) {                               \
                 case 1:                                                 \
@@ -170,8 +170,8 @@
 
 #define put_user(x,p)							\
 	({								\
-		const register typeof(*(p)) __r1 asm("r1") = (x);	\
-		const register typeof(*(p)) *__p asm("r0") = (p);	\
+		register const typeof(*(p)) __r1 asm("r1") = (x);	\
+		register const typeof(*(p)) *__p asm("r0") = (p);	\
 		register int __e asm("r0");				\
 		switch (sizeof(*(p))) {					\
 		case 1:							\
diff --git a/include/asm-avr32/arch-at32ap/at91_pdc.h b/include/asm-avr32/arch-at32ap/at91_pdc.h
deleted file mode 100644
index 79d6e02..0000000
--- a/include/asm-avr32/arch-at32ap/at91_pdc.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * include/asm-arm/arch-at91rm9200/at91_pdc.h
- *
- * Copyright (C) 2005 Ivan Kokshaysky
- * Copyright (C) SAN People
- *
- * Peripheral Data Controller (PDC) registers.
- * Based on AT91RM9200 datasheet revision E.
- *
- * 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.
- */
-
-#ifndef AT91_PDC_H
-#define AT91_PDC_H
-
-#define AT91_PDC_RPR		0x100	/* Receive Pointer Register */
-#define AT91_PDC_RCR		0x104	/* Receive Counter Register */
-#define AT91_PDC_TPR		0x108	/* Transmit Pointer Register */
-#define AT91_PDC_TCR		0x10c	/* Transmit Counter Register */
-#define AT91_PDC_RNPR		0x110	/* Receive Next Pointer Register */
-#define AT91_PDC_RNCR		0x114	/* Receive Next Counter Register */
-#define AT91_PDC_TNPR		0x118	/* Transmit Next Pointer Register */
-#define AT91_PDC_TNCR		0x11c	/* Transmit Next Counter Register */
-
-#define AT91_PDC_PTCR		0x120	/* Transfer Control Register */
-#define		AT91_PDC_RXTEN		(1 << 0)	/* Receiver Transfer Enable */
-#define		AT91_PDC_RXTDIS		(1 << 1)	/* Receiver Transfer Disable */
-#define		AT91_PDC_TXTEN		(1 << 8)	/* Transmitter Transfer Enable */
-#define		AT91_PDC_TXTDIS		(1 << 9)	/* Transmitter Transfer Disable */
-
-#define AT91_PDC_PTSR		0x124	/* Transfer Status Register */
-
-#endif
diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
index 5e657eb..449f3f2 100644
--- a/include/asm-i386/acpi.h
+++ b/include/asm-i386/acpi.h
@@ -127,6 +127,7 @@
 #define acpi_ioapic 0
 static inline void acpi_noirq_set(void) { }
 static inline void acpi_disable_pci(void) { }
+static inline void disable_acpi(void) { }
 
 #endif	/* !CONFIG_ACPI */
 
diff --git a/include/asm-ia64/kexec.h b/include/asm-ia64/kexec.h
index 01c36b0..f2ad469 100644
--- a/include/asm-ia64/kexec.h
+++ b/include/asm-ia64/kexec.h
@@ -23,7 +23,7 @@
 
 extern struct kimage *ia64_kimage;
 DECLARE_PER_CPU(u64, ia64_mca_pal_base);
-const extern unsigned int relocate_new_kernel_size;
+extern const unsigned int relocate_new_kernel_size;
 extern void relocate_new_kernel(unsigned long, unsigned long,
 		struct ia64_boot_param *, unsigned long);
 static inline void
diff --git a/include/asm-ia64/pal.h b/include/asm-ia64/pal.h
index bc76815..e43021a 100644
--- a/include/asm-ia64/pal.h
+++ b/include/asm-ia64/pal.h
@@ -32,7 +32,7 @@
 #define PAL_CACHE_FLUSH		1	/* flush i/d cache */
 #define PAL_CACHE_INFO		2	/* get detailed i/d cache info */
 #define PAL_CACHE_INIT		3	/* initialize i/d cache */
-#define PAL_CACHE_SUMMARY	4	/* get summary of cache heirarchy */
+#define PAL_CACHE_SUMMARY	4	/* get summary of cache hierarchy */
 #define PAL_MEM_ATTRIB		5	/* list supported memory attributes */
 #define PAL_PTCE_INFO		6	/* purge TLB info */
 #define PAL_VM_INFO		7	/* return supported virtual memory features */
@@ -113,14 +113,14 @@
 						 */
 #define PAL_STATUS_REQUIRES_MEMORY	(-9)	/* Call requires PAL memory buffer */
 
-/* Processor cache level in the heirarchy */
+/* Processor cache level in the hierarchy */
 typedef u64				pal_cache_level_t;
 #define PAL_CACHE_LEVEL_L0		0	/* L0 */
 #define PAL_CACHE_LEVEL_L1		1	/* L1 */
 #define PAL_CACHE_LEVEL_L2		2	/* L2 */
 
 
-/* Processor cache type at a particular level in the heirarchy */
+/* Processor cache type at a particular level in the hierarchy */
 
 typedef u64				pal_cache_type_t;
 #define PAL_CACHE_TYPE_INSTRUCTION	1	/* Instruction cache */
@@ -272,14 +272,14 @@
 #define PAL_CACHE_PROT_METHOD_ECC		3	/* ECC protection */
 
 
-/* Processor cache line identification in the heirarchy */
+/* Processor cache line identification in the hierarchy */
 typedef union pal_cache_line_id_u {
 	u64			pclid_data;
 	struct {
 		u64		cache_type	: 8,	/* 7-0 cache type */
 				level		: 8,	/* 15-8 level of the
 							 * cache in the
-							 * heirarchy.
+							 * hierarchy.
 							 */
 				way		: 8,	/* 23-16 way in the set
 							 */
@@ -292,7 +292,7 @@
 		u64		cache_type	: 8,	/* 7-0 cache type */
 				level		: 8,	/* 15-8 level of the
 							 * cache in the
-							 * heirarchy.
+							 * hierarchy.
 							 */
 				way		: 8,	/* 23-16 way in the set
 							 */
@@ -978,7 +978,7 @@
 	return iprv.status;
 }
 
-/* Return summary information about the heirarchy of caches controlled by the processor */
+/* Return summary information about the hierarchy of caches controlled by the processor */
 static inline s64
 ia64_pal_cache_summary (u64 *cache_levels, u64 *unique_caches)
 {
diff --git a/include/asm-mips/abi.h b/include/asm-mips/abi.h
index 1ce0518..1dd74fb 100644
--- a/include/asm-mips/abi.h
+++ b/include/asm-mips/abi.h
@@ -13,13 +13,13 @@
 #include <asm/siginfo.h>
 
 struct mips_abi {
-	void (* const do_signal)(struct pt_regs *regs);
 	int (* const setup_frame)(struct k_sigaction * ka,
 	                          struct pt_regs *regs, int signr,
 	                          sigset_t *set);
 	int (* const setup_rt_frame)(struct k_sigaction * ka,
 	                       struct pt_regs *regs, int signr,
 	                       sigset_t *set, siginfo_t *info);
+	const unsigned long	restart;
 };
 
 #endif /* _ASM_ABI_H */
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index 06c0822..89436b9 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1994 - 1997, 1999, 2000, 06  Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (c) 1994 - 1997, 99, 2000, 06, 07  Ralf Baechle (ralf@linux-mips.org)
  * Copyright (c) 1999, 2000  Silicon Graphics, Inc.
  */
 #ifndef _ASM_BITOPS_H
@@ -24,11 +24,15 @@
 #define SZLONG_MASK 31UL
 #define __LL		"ll	"
 #define __SC		"sc	"
+#define __INS		"ins    "
+#define __EXT		"ext    "
 #elif (_MIPS_SZLONG == 64)
 #define SZLONG_LOG 6
 #define SZLONG_MASK 63UL
 #define __LL		"lld	"
 #define __SC		"scd	"
+#define __INS		"dins    "
+#define __EXT		"dext    "
 #endif
 
 /*
@@ -62,6 +66,19 @@
 		"	.set	mips0					\n"
 		: "=&r" (temp), "=m" (*m)
 		: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
+#ifdef CONFIG_CPU_MIPSR2
+	} else if (__builtin_constant_p(nr)) {
+		__asm__ __volatile__(
+		"1:	" __LL "%0, %1			# set_bit	\n"
+		"	" __INS "%0, %4, %2, 1				\n"
+		"	" __SC "%0, %1					\n"
+		"	beqz	%0, 2f					\n"
+		"	.subsection 2					\n"
+		"2:	b	1b					\n"
+		"	.previous					\n"
+		: "=&r" (temp), "=m" (*m)
+		: "ir" (nr & SZLONG_MASK), "m" (*m), "r" (~0));
+#endif /* CONFIG_CPU_MIPSR2 */
 	} else if (cpu_has_llsc) {
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -113,6 +130,19 @@
 		"	.set	mips0					\n"
 		: "=&r" (temp), "=m" (*m)
 		: "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m));
+#ifdef CONFIG_CPU_MIPSR2
+	} else if (__builtin_constant_p(nr)) {
+		__asm__ __volatile__(
+		"1:	" __LL "%0, %1			# clear_bit	\n"
+		"	" __INS "%0, $0, %2, 1				\n"
+		"	" __SC "%0, %1					\n"
+		"	beqz	%0, 2f					\n"
+		"	.subsection 2					\n"
+		"2:	b	1b					\n"
+		"	.previous					\n"
+		: "=&r" (temp), "=m" (*m)
+		: "ir" (nr & SZLONG_MASK), "m" (*m));
+#endif /* CONFIG_CPU_MIPSR2 */
 	} else if (cpu_has_llsc) {
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -291,6 +321,26 @@
 		: "memory");
 
 		return res != 0;
+#ifdef CONFIG_CPU_MIPSR2
+	} else if (__builtin_constant_p(nr)) {
+		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+		unsigned long temp, res;
+
+		__asm__ __volatile__(
+		"1:	" __LL	"%0, %1		# test_and_clear_bit	\n"
+		"	" __EXT "%2, %0, %3, 1				\n"
+		"	" __INS	"%0, $0, %3, 1				\n"
+		"	" __SC 	"%0, %1					\n"
+		"	beqz	%0, 2f					\n"
+		"	.subsection 2					\n"
+		"2:	b	1b					\n"
+		"	.previous					\n"
+		: "=&r" (temp), "=m" (*m), "=&r" (res)
+		: "ri" (nr & SZLONG_MASK), "m" (*m)
+		: "memory");
+
+		return res;
+#endif
 	} else if (cpu_has_llsc) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp, res;
diff --git a/include/asm-mips/compat-signal.h b/include/asm-mips/compat-signal.h
index 6720770..6599a90 100644
--- a/include/asm-mips/compat-signal.h
+++ b/include/asm-mips/compat-signal.h
@@ -5,6 +5,11 @@
 #include <linux/compat.h>
 #include <linux/compiler.h>
 
+#include <asm/signal.h>
+#include <asm/siginfo.h>
+
+#include <asm/uaccess.h>
+
 static inline int __copy_conv_sigset_to_user(compat_sigset_t __user *d,
 	const sigset_t *s)
 {
@@ -33,9 +38,6 @@
 	BUG_ON(sizeof(*d) != sizeof(*s));
 	BUG_ON(_NSIG_WORDS != 2);
 
-	if (unlikely(!access_ok(VERIFY_READ, d, sizeof(*d))))
-		return -EFAULT;
-
 #ifdef CONFIG_CPU_BIG_ENDIAN
 	err  = __get_user(u->c.sig[1], &s->sig[0]);
 	err |= __get_user(u->c.sig[0], &s->sig[1]);
diff --git a/include/asm-mips/ds1216.h b/include/asm-mips/ds1216.h
new file mode 100644
index 0000000..1ff8b73
--- /dev/null
+++ b/include/asm-mips/ds1216.h
@@ -0,0 +1,31 @@
+#ifndef _DS1216_H
+#define _DS1216_H
+
+extern volatile unsigned char *ds1216_base;
+unsigned long ds1216_get_cmos_time(void);
+int ds1216_set_rtc_mmss(unsigned long nowtime);
+
+#define DS1216_SEC_BYTE		1
+#define DS1216_MIN_BYTE		2
+#define DS1216_HOUR_BYTE	3
+#define DS1216_HOUR_MASK	(0x1f)
+#define DS1216_AMPM_MASK	(1<<5)
+#define DS1216_1224_MASK	(1<<7)
+#define DS1216_DAY_BYTE		4
+#define DS1216_DAY_MASK		(0x7)
+#define DS1216_DATE_BYTE	5
+#define DS1216_DATE_MASK	(0x3f)
+#define DS1216_MONTH_BYTE	6
+#define DS1216_MONTH_MASK	(0x1f)
+#define DS1216_YEAR_BYTE	7
+
+#define DS1216_SEC(buf)		(buf[DS1216_SEC_BYTE])
+#define DS1216_MIN(buf)		(buf[DS1216_MIN_BYTE])
+#define DS1216_HOUR(buf)	(buf[DS1216_HOUR_BYTE] & DS1216_HOUR_MASK)
+#define DS1216_AMPM(buf)	(buf[DS1216_HOUR_BYTE] & DS1216_AMPM_MASK)
+#define DS1216_1224(buf)	(buf[DS1216_HOUR_BYTE] & DS1216_1224_MASK)
+#define DS1216_DATE(buf)	(buf[DS1216_DATE_BYTE] & DS1216_DATE_MASK)
+#define DS1216_MONTH(buf)	(buf[DS1216_MONTH_BYTE] & DS1216_MONTH_MASK)
+#define DS1216_YEAR(buf)	(buf[DS1216_YEAR_BYTE])
+
+#endif
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h
index b6a2eb8..92ec261 100644
--- a/include/asm-mips/io.h
+++ b/include/asm-mips/io.h
@@ -20,6 +20,7 @@
 #include <asm/byteorder.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
+#include <asm-generic/iomap.h>
 #include <asm/page.h>
 #include <asm/pgtable-bits.h>
 #include <asm/processor.h>
@@ -518,34 +519,6 @@
 }
 
 /*
- * Memory Mapped I/O
- */
-#define ioread8(addr)		readb(addr)
-#define ioread16(addr)		readw(addr)
-#define ioread32(addr)		readl(addr)
-
-#define iowrite8(b,addr)	writeb(b,addr)
-#define iowrite16(w,addr)	writew(w,addr)
-#define iowrite32(l,addr)	writel(l,addr)
-
-#define ioread8_rep(a,b,c)	readsb(a,b,c)
-#define ioread16_rep(a,b,c)	readsw(a,b,c)
-#define ioread32_rep(a,b,c)	readsl(a,b,c)
-
-#define iowrite8_rep(a,b,c)	writesb(a,b,c)
-#define iowrite16_rep(a,b,c)	writesw(a,b,c)
-#define iowrite32_rep(a,b,c)	writesl(a,b,c)
-
-/* Create a virtual mapping cookie for an IO port range */
-extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
-extern void ioport_unmap(void __iomem *);
-
-/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
-struct pci_dev;
-extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
-extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
-
-/*
  * ISA space is 'always mapped' on currently supported MIPS systems, no need
  * to explicitly ioremap() it. The fact that the ISA IO space is mapped
  * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
diff --git a/include/asm-mips/mach-rm/cpu-feature-overrides.h b/include/asm-mips/mach-rm/cpu-feature-overrides.h
index 11410ae..7e07283 100644
--- a/include/asm-mips/mach-rm/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-rm/cpu-feature-overrides.h
@@ -21,9 +21,7 @@
 #define cpu_has_watch		0
 #define cpu_has_mips16		0
 #define cpu_has_divec		0
-#define cpu_has_vce		0
 #define cpu_has_cache_cdex_p	1
-#define cpu_has_cache_cdex_s	0
 #define cpu_has_prefetch	0
 #define cpu_has_mcheck		0
 #define cpu_has_ejtag		0
@@ -35,9 +33,6 @@
 #define cpu_has_nofpuex		0
 #define cpu_has_64bits		1
 
-#define cpu_dcache_line_size()	32
-#define cpu_icache_line_size()	32
-
 #define cpu_has_mips32r1	0
 #define cpu_has_mips32r2	0
 #define cpu_has_mips64r1	0
diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h
index 7f0f120..3eea3ba 100644
--- a/include/asm-mips/pci.h
+++ b/include/asm-mips/pci.h
@@ -32,6 +32,7 @@
 	unsigned long mem_offset;
 	struct resource *io_resource;
 	unsigned long io_offset;
+	unsigned long io_map_base;
 
 	unsigned int index;
 	/* For compatibility with current (as of July 2003) pciutils
diff --git a/include/asm-mips/pgalloc.h b/include/asm-mips/pgalloc.h
index af121c6..5685d4f 100644
--- a/include/asm-mips/pgalloc.h
+++ b/include/asm-mips/pgalloc.h
@@ -130,4 +130,6 @@
 
 #define check_pgt_cache()	do { } while (0)
 
+extern void pagetable_init(void);
+
 #endif /* _ASM_PGALLOC_H */
diff --git a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h
index 3c175a7..9729474 100644
--- a/include/asm-mips/sigcontext.h
+++ b/include/asm-mips/sigcontext.h
@@ -42,6 +42,7 @@
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32
 
+#include <linux/posix_types.h>
 /*
  * Keep this struct definition in sync with the sigcontext fragment
  * in arch/mips/tools/offset.c
@@ -53,27 +54,25 @@
  * entries, add sc_dsp and sc_reserved for padding.  No prisoners.
  */
 struct sigcontext {
-	unsigned long	sc_regs[32];
-	unsigned long	sc_fpregs[32];
-	unsigned long	sc_mdhi;
-	unsigned long	sc_hi1;
-	unsigned long	sc_hi2;
-	unsigned long	sc_hi3;
-	unsigned long	sc_mdlo;
-	unsigned long	sc_lo1;
-	unsigned long	sc_lo2;
-	unsigned long	sc_lo3;
-	unsigned long	sc_pc;
-	unsigned int	sc_fpc_csr;
-	unsigned int	sc_used_math;
-	unsigned int	sc_dsp;
-	unsigned int	sc_reserved;
+	__u64	sc_regs[32];
+	__u64	sc_fpregs[32];
+	__u64	sc_mdhi;
+	__u64	sc_hi1;
+	__u64	sc_hi2;
+	__u64	sc_hi3;
+	__u64	sc_mdlo;
+	__u64	sc_lo1;
+	__u64	sc_lo2;
+	__u64	sc_lo3;
+	__u64	sc_pc;
+	__u32	sc_fpc_csr;
+	__u32	sc_used_math;
+	__u32	sc_dsp;
+	__u32	sc_reserved;
 };
 
 #ifdef __KERNEL__
 
-#include <linux/posix_types.h>
-
 struct sigcontext32 {
 	__u32		sc_regmask;	/* Unused */
 	__u32		sc_status;	/* Unused */
diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h
index 8b391a2..7a28989 100644
--- a/include/asm-mips/signal.h
+++ b/include/asm-mips/signal.h
@@ -137,23 +137,6 @@
 
 #define ptrace_signal_deliver(regs, cookie) do { } while (0)
 
-struct pt_regs;
-extern void do_signal(struct pt_regs *regs);
-extern void do_signal32(struct pt_regs *regs);
-
-extern int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
-        int signr, sigset_t *set);
-extern int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
-        int signr, sigset_t *set, siginfo_t *info);
-
-extern int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
-        int signr, sigset_t *set);
-extern int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
-        int signr, sigset_t *set, siginfo_t *info);
-
-extern int setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs,
-        int signr, sigset_t *set, siginfo_t *info);
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_SIGNAL_H */
diff --git a/include/asm-mips/sni.h b/include/asm-mips/sni.h
index b9ba54d..62f9be6 100644
--- a/include/asm-mips/sni.h
+++ b/include/asm-mips/sni.h
@@ -6,12 +6,72 @@
  * for more details.
  *
  * Copyright (C) 1997, 1998 by Ralf Baechle
+ * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
  */
 #ifndef __ASM_SNI_H
 #define __ASM_SNI_H
 
+extern unsigned int sni_brd_type;
+
+#define SNI_BRD_10                 2
+#define SNI_BRD_10NEW              3
+#define SNI_BRD_TOWER_OASIC        4
+#define SNI_BRD_MINITOWER          5
+#define SNI_BRD_PCI_TOWER          6
+#define SNI_BRD_RM200              7
+#define SNI_BRD_PCI_MTOWER         8
+#define SNI_BRD_PCI_DESKTOP        9
+#define SNI_BRD_PCI_TOWER_CPLUS   10
+#define SNI_BRD_PCI_MTOWER_CPLUS  11
+
+/* RM400 cpu types */
+#define SNI_CPU_M8021           0x01
+#define SNI_CPU_M8030           0x04
+#define SNI_CPU_M8031           0x06
+#define SNI_CPU_M8034           0x0f
+#define SNI_CPU_M8037           0x07
+#define SNI_CPU_M8040           0x05
+#define SNI_CPU_M8043           0x09
+#define SNI_CPU_M8050           0x0b
+#define SNI_CPU_M8053           0x0d
+
 #define SNI_PORT_BASE		0xb4000000
 
+#ifndef __MIPSEL__
+/*
+ * ASIC PCI registers for big endian configuration.
+ */
+#define PCIMT_UCONF		0xbfff0004
+#define PCIMT_IOADTIMEOUT2	0xbfff000c
+#define PCIMT_IOMEMCONF		0xbfff0014
+#define PCIMT_IOMMU		0xbfff001c
+#define PCIMT_IOADTIMEOUT1	0xbfff0024
+#define PCIMT_DMAACCESS		0xbfff002c
+#define PCIMT_DMAHIT		0xbfff0034
+#define PCIMT_ERRSTATUS		0xbfff003c
+#define PCIMT_ERRADDR		0xbfff0044
+#define PCIMT_SYNDROME		0xbfff004c
+#define PCIMT_ITPEND		0xbfff0054
+#define  IT_INT2		0x01
+#define  IT_INTD		0x02
+#define  IT_INTC		0x04
+#define  IT_INTB		0x08
+#define  IT_INTA		0x10
+#define  IT_EISA		0x20
+#define  IT_SCSI		0x40
+#define  IT_ETH			0x80
+#define PCIMT_IRQSEL		0xbfff005c
+#define PCIMT_TESTMEM		0xbfff0064
+#define PCIMT_ECCREG		0xbfff006c
+#define PCIMT_CONFIG_ADDRESS	0xbfff0074
+#define PCIMT_ASIC_ID		0xbfff007c	/* read */
+#define PCIMT_SOFT_RESET	0xbfff007c	/* write */
+#define PCIMT_PIA_OE		0xbfff0084
+#define PCIMT_PIA_DATAOUT	0xbfff008c
+#define PCIMT_PIA_DATAIN	0xbfff0094
+#define PCIMT_CACHECONF		0xbfff009c
+#define PCIMT_INVSPACE		0xbfff00a4
+#else
 /*
  * ASIC PCI registers for little endian configuration.
  */
@@ -45,6 +105,8 @@
 #define PCIMT_PIA_DATAIN	0xbfff0090
 #define PCIMT_CACHECONF		0xbfff0098
 #define PCIMT_INVSPACE		0xbfff00a0
+#endif
+
 #define PCIMT_PCI_CONF		0xbfff0100
 
 /*
@@ -73,6 +135,36 @@
 #define PCIMT_PWDN		0xbfdf0000
 
 /*
+ * A20R based boards
+ */
+#define A20R_PT_CLOCK_BASE      0xbc040000
+#define A20R_PT_TIM0_ACK        0xbc050000
+#define A20R_PT_TIM1_ACK        0xbc060000
+
+#define SNI_MIPS_IRQ_CPU_BASE   16
+#define SNI_MIPS_IRQ_CPU_TIMER  (SNI_MIPS_IRQ_CPU_BASE+7)
+
+#define SNI_A20R_IRQ_BASE       SNI_MIPS_IRQ_CPU_BASE
+#define SNI_A20R_IRQ_TIMER      (SNI_A20R_IRQ_BASE+5)
+
+#define SNI_DS1216_A20R_BASE    0xbc081ffc
+#define SNI_DS1216_RM200_BASE   0xbcd41ffc
+
+#define SNI_PCIT_INT_REG        0xbfff000c
+
+#define SNI_PCIT_INT_START      24
+#define SNI_PCIT_INT_END        30
+
+#define PCIT_IRQ_ETHERNET       (SNI_MIPS_IRQ_CPU_BASE + 5)
+#define PCIT_IRQ_INTA           (SNI_PCIT_INT_START + 0)
+#define PCIT_IRQ_INTB           (SNI_PCIT_INT_START + 1)
+#define PCIT_IRQ_INTC           (SNI_PCIT_INT_START + 2)
+#define PCIT_IRQ_INTD           (SNI_PCIT_INT_START + 3)
+#define PCIT_IRQ_SCSI0          (SNI_PCIT_INT_START + 4)
+#define PCIT_IRQ_SCSI1          (SNI_PCIT_INT_START + 5)
+
+
+/*
  * Interrupt 0-16 are EISA interrupts.  Interrupts from 16 on are assigned
  * to the other interrupts generated by ASIC PCI.
  *
@@ -80,18 +172,22 @@
  * ASIC PCI interrupt.
  */
 #define PCIMT_KEYBOARD_IRQ	 1
-#define PCIMT_IRQ_INT2		16
-#define PCIMT_IRQ_INTD		17
-#define PCIMT_IRQ_INTC		18
-#define PCIMT_IRQ_INTB		19
-#define PCIMT_IRQ_INTA		20
-#define PCIMT_IRQ_EISA		21
-#define PCIMT_IRQ_SCSI		22
-#define PCIMT_IRQ_ETHERNET	23
+#define PCIMT_IRQ_INT2		24
+#define PCIMT_IRQ_INTD		25
+#define PCIMT_IRQ_INTC		26
+#define PCIMT_IRQ_INTB		27
+#define PCIMT_IRQ_INTA		28
+#define PCIMT_IRQ_EISA		29
+#define PCIMT_IRQ_SCSI		30
+
+#define PCIMT_IRQ_ETHERNET	(SNI_MIPS_IRQ_CPU_BASE+6)
+
+#if 0
 #define PCIMT_IRQ_TEMPERATURE	24
 #define PCIMT_IRQ_EISA_NMI	25
 #define PCIMT_IRQ_POWER_OFF	26
 #define PCIMT_IRQ_BUTTON	27
+#endif
 
 /*
  * Base address for the mapped 16mb EISA bus segment.
@@ -101,4 +197,24 @@
 /* PCI EISA Interrupt acknowledge  */
 #define PCIMT_INT_ACKNOWLEDGE	0xba000000
 
+/* board specific init functions */
+extern void sni_a20r_init (void);
+extern void sni_pcit_init (void);
+extern void sni_rm200_init (void);
+extern void sni_pcimt_init (void);
+
+/* board specific irq init functions */
+extern void sni_a20r_irq_init (void);
+extern void sni_pcit_irq_init (void);
+extern void sni_pcit_cplus_irq_init (void);
+extern void sni_rm200_irq_init (void);
+extern void sni_pcimt_irq_init (void);
+
+/* timer inits */
+extern void sni_cpu_time_init(void);
+
+/* common irq stuff */
+extern void (*sni_hwint)(void);
+extern struct irqaction sni_isa_irq;
+
 #endif /* __ASM_SNI_H */
diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h
index 3eff8d8..c62c20e 100644
--- a/include/asm-mips/uaccess.h
+++ b/include/asm-mips/uaccess.h
@@ -435,8 +435,32 @@
 	__cu_len;							\
 })
 
-#define __copy_to_user_inatomic __copy_to_user
-#define __copy_from_user_inatomic __copy_from_user
+#define __copy_to_user_inatomic(to,from,n)				\
+({									\
+	void __user *__cu_to;						\
+	const void *__cu_from;						\
+	long __cu_len;							\
+									\
+	__cu_to = (to);							\
+	__cu_from = (from);						\
+	__cu_len = (n);							\
+	__cu_len = __invoke_copy_to_user(__cu_to, __cu_from, __cu_len);	\
+	__cu_len;							\
+})
+
+#define __copy_from_user_inatomic(to,from,n)				\
+({									\
+	void *__cu_to;							\
+	const void __user *__cu_from;					\
+	long __cu_len;							\
+									\
+	__cu_to = (to);							\
+	__cu_from = (from);						\
+	__cu_len = (n);							\
+	__cu_len = __invoke_copy_from_user_inatomic(__cu_to, __cu_from,	\
+	                                            __cu_len);		\
+	__cu_len;							\
+})
 
 /*
  * copy_to_user: - Copy a block of data into user space.
@@ -490,6 +514,29 @@
 	__cu_len_r;							\
 })
 
+#define __invoke_copy_from_user_inatomic(to,from,n)			\
+({									\
+	register void *__cu_to_r __asm__ ("$4");			\
+	register const void __user *__cu_from_r __asm__ ("$5");		\
+	register long __cu_len_r __asm__ ("$6");			\
+									\
+	__cu_to_r = (to);						\
+	__cu_from_r = (from);						\
+	__cu_len_r = (n);						\
+	__asm__ __volatile__(						\
+	".set\tnoreorder\n\t"						\
+	__MODULE_JAL(__copy_user_inatomic)				\
+	".set\tnoat\n\t"						\
+	__UA_ADDU "\t$1, %1, %2\n\t"					\
+	".set\tat\n\t"							\
+	".set\treorder"							\
+	: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)	\
+	:								\
+	: "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31",		\
+	  "memory");							\
+	__cu_len_r;							\
+})
+
 /*
  * __copy_from_user: - Copy a block of data from user space, with less checking.
  * @to:   Destination address, in kernel space.
diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h
index f038e33..2ce4b6b 100644
--- a/include/asm-powerpc/atomic.h
+++ b/include/asm-powerpc/atomic.h
@@ -165,7 +165,8 @@
 	return t;
 }
 
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_cmpxchg(v, o, n) \
+	((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 /**
@@ -413,6 +414,43 @@
 	return t;
 }
 
+#define atomic64_cmpxchg(v, o, n) \
+	((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+	long t;
+
+	__asm__ __volatile__ (
+	LWSYNC_ON_SMP
+"1:	ldarx	%0,0,%1		# atomic_add_unless\n\
+	cmpd	0,%0,%3 \n\
+	beq-	2f \n\
+	add	%0,%2,%0 \n"
+"	stdcx.	%0,0,%1 \n\
+	bne-	1b \n"
+	ISYNC_ON_SMP
+"	subf	%0,%2,%0 \n\
+2:"
+	: "=&r" (t)
+	: "r" (&v->counter), "r" (a), "r" (u)
+	: "cc", "memory");
+
+	return t != u;
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
 #endif /* __powerpc64__ */
 
 #include <asm-generic/atomic.h>
diff --git a/include/asm-powerpc/dcr-native.h b/include/asm-powerpc/dcr-native.h
index d7a1bc1..05af081 100644
--- a/include/asm-powerpc/dcr-native.h
+++ b/include/asm-powerpc/dcr-native.h
@@ -26,8 +26,8 @@
 
 #define DCR_MAP_OK(host)	(1)
 
-#define dcr_map(dev, dcr_n, dcr_c)	{}
-#define dcr_unmap(host, dcr_n, dcr_c)	{}
+#define dcr_map(dev, dcr_n, dcr_c)	((dcr_host_t){})
+#define dcr_unmap(host, dcr_n, dcr_c)	do {} while (0)
 #define dcr_read(host, dcr_n)		mfdcr(dcr_n)
 #define dcr_write(host, dcr_n, value)	mtdcr(dcr_n, value)
 
diff --git a/include/asm-powerpc/pmi.h b/include/asm-powerpc/pmi.h
new file mode 100644
index 0000000..cb0f8aa
--- /dev/null
+++ b/include/asm-powerpc/pmi.h
@@ -0,0 +1,67 @@
+#ifndef _POWERPC_PMI_H
+#define _POWERPC_PMI_H
+
+/*
+ * Definitions for talking with PMI device on PowerPC
+ *
+ * PMI (Platform Management Interrupt) is a way to communicate
+ * with the BMC (Baseboard Management Controller) via interrupts.
+ * Unlike IPMI it is bidirectional and has a low latency.
+ *
+ * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
+ *
+ * Author: Christian Krafft <krafft@de.ibm.com>
+ *
+ * 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, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef __KERNEL__
+
+#include <asm/of_device.h>
+
+#define PMI_TYPE_FREQ_CHANGE	0x01
+#define PMI_READ_TYPE		0
+#define PMI_READ_DATA0		1
+#define PMI_READ_DATA1		2
+#define PMI_READ_DATA2		3
+#define PMI_WRITE_TYPE		4
+#define PMI_WRITE_DATA0		5
+#define PMI_WRITE_DATA1		6
+#define PMI_WRITE_DATA2		7
+
+#define PMI_ACK			0x80
+
+#define PMI_TIMEOUT		100
+
+typedef struct {
+	u8	type;
+	u8	data0;
+	u8	data1;
+	u8	data2;
+} pmi_message_t;
+
+struct pmi_handler {
+	struct list_head node;
+	u8 type;
+	void (*handle_pmi_message) (struct of_device *, pmi_message_t);
+};
+
+void pmi_register_handler(struct of_device *, struct pmi_handler *);
+void pmi_unregister_handler(struct of_device *, struct pmi_handler *);
+
+void pmi_send_message(struct of_device *, pmi_message_t);
+
+#endif /* __KERNEL__ */
+#endif /* _POWERPC_PMI_H */
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index 0afee17..020ed01 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -255,6 +255,8 @@
 /* CPU OF node matching */
 struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
 
+/* Get the MAC address */
+extern const void *of_get_mac_address(struct device_node *np);
 
 /*
  * OF interrupt mapping
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h
index e5982ad..821581a 100644
--- a/include/asm-powerpc/ps3.h
+++ b/include/asm-powerpc/ps3.h
@@ -355,13 +355,7 @@
 
 /* vuart routines */
 
-struct ps3_vuart_stats {
-	unsigned long bytes_written;
-	unsigned long bytes_read;
-	unsigned long tx_interrupts;
-	unsigned long rx_interrupts;
-	unsigned long disconnect_interrupts;
-};
+struct ps3_vuart_port_priv;
 
 /**
  * struct ps3_vuart_port_device - a device on a vuart port
@@ -370,24 +364,17 @@
 struct ps3_vuart_port_device {
 	enum ps3_match_id match_id;
 	struct device core;
+	struct ps3_vuart_port_priv* priv; /* private driver variables */
 
-	/* private driver variables */
-	unsigned int port_number;
-	u64 interrupt_mask;
-	struct {
-		spinlock_t lock;
-		struct list_head head;
-	} tx_list;
-	struct {
-		unsigned long bytes_held;
-		spinlock_t lock;
-		struct list_head head;
-	} rx_list;
-	struct ps3_vuart_stats stats;
 };
 
 int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev);
 
+/* system manager */
+
+void ps3_sys_manager_restart(void);
+void ps3_sys_manager_power_off(void);
+
 struct ps3_prealloc {
     const char *name;
     void *address;
diff --git a/include/asm-powerpc/ucc_slow.h b/include/asm-powerpc/ucc_slow.h
index 1babad9..fdaac9d 100644
--- a/include/asm-powerpc/ucc_slow.h
+++ b/include/asm-powerpc/ucc_slow.h
@@ -150,7 +150,7 @@
 	int ucc_num;
 	enum qe_clock rx_clock;
 	enum qe_clock tx_clock;
-	struct ucc_slow *regs;
+	u32 regs;
 	int irq;
 	u16 uccm_mask;
 	int data_mem_part;
@@ -199,9 +199,9 @@
 				   and length for first BD in a frame */
 	u32 tx_base_offset;	/* first BD in Tx BD table offset (In MURAM) */
 	u32 rx_base_offset;	/* first BD in Rx BD table offset (In MURAM) */
-	u8 *confBd;		/* next BD for confirm after Tx */
-	u8 *tx_bd;		/* next BD for new Tx request */
-	u8 *rx_bd;		/* next BD to collect after Rx */
+	struct qe_bd *confBd;	/* next BD for confirm after Tx */
+	struct qe_bd *tx_bd;	/* next BD for new Tx request */
+	struct qe_bd *rx_bd;	/* next BD to collect after Rx */
 	void *p_rx_frame;	/* accumulating receive frame */
 	u16 *p_ucce;		/* a pointer to the event register in memory.
 				 */
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 815f1fb..8bcfaa4 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -75,7 +75,7 @@
 
 typedef int (*acpi_table_handler) (struct acpi_table_header *table);
 
-typedef int (*acpi_madt_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
+typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
 
 char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
 unsigned long acpi_find_rsdp (void);
@@ -85,8 +85,10 @@
 
 int acpi_table_init (void);
 int acpi_table_parse (char *id, acpi_table_handler handler);
-int acpi_table_parse_madt (enum acpi_madt_type id, acpi_madt_entry_handler handler, unsigned int max_entries);
-int acpi_table_parse_srat (enum acpi_srat_type id, acpi_madt_entry_handler handler, unsigned int max_entries);
+int __init acpi_table_parse_entries(char *id, unsigned long table_size,
+	int entry_id, acpi_table_entry_handler handler, unsigned int max_entries);
+int acpi_table_parse_madt (enum acpi_madt_type id, acpi_table_entry_handler handler, unsigned int max_entries);
+int acpi_table_parse_srat (enum acpi_srat_type id, acpi_table_entry_handler handler, unsigned int max_entries);
 int acpi_parse_mcfg (struct acpi_table_header *header);
 void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
 void acpi_table_print_srat_entry (struct acpi_subtable_header *srat);
diff --git a/include/linux/atmel_pdc.h b/include/linux/atmel_pdc.h
new file mode 100644
index 0000000..5058a31
--- /dev/null
+++ b/include/linux/atmel_pdc.h
@@ -0,0 +1,36 @@
+/*
+ * include/linux/atmel_pdc.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Peripheral Data Controller (PDC) registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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.
+ */
+
+#ifndef ATMEL_PDC_H
+#define ATMEL_PDC_H
+
+#define ATMEL_PDC_RPR		0x100	/* Receive Pointer Register */
+#define ATMEL_PDC_RCR		0x104	/* Receive Counter Register */
+#define ATMEL_PDC_TPR		0x108	/* Transmit Pointer Register */
+#define ATMEL_PDC_TCR		0x10c	/* Transmit Counter Register */
+#define ATMEL_PDC_RNPR		0x110	/* Receive Next Pointer Register */
+#define ATMEL_PDC_RNCR		0x114	/* Receive Next Counter Register */
+#define ATMEL_PDC_TNPR		0x118	/* Transmit Next Pointer Register */
+#define ATMEL_PDC_TNCR		0x11c	/* Transmit Next Counter Register */
+
+#define ATMEL_PDC_PTCR		0x120	/* Transfer Control Register */
+#define		ATMEL_PDC_RXTEN		(1 << 0)	/* Receiver Transfer Enable */
+#define		ATMEL_PDC_RXTDIS	(1 << 1)	/* Receiver Transfer Disable */
+#define		ATMEL_PDC_TXTEN		(1 << 8)	/* Transmitter Transfer Enable */
+#define		ATMEL_PDC_TXTDIS	(1 << 9)	/* Transmitter Transfer Disable */
+
+#define ATMEL_PDC_PTSR		0x124	/* Transfer Status Register */
+
+#endif
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 0e07db6..229fa01 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -89,6 +89,7 @@
 #define AUDIT_MQ_NOTIFY		1314	/* POSIX MQ notify record type */
 #define AUDIT_MQ_GETSETATTR	1315	/* POSIX MQ get/set attribute record type */
 #define AUDIT_KERNEL_OTHER	1316	/* For use by 3rd party modules */
+#define AUDIT_FD_PAIR		1317    /* audit record for pipe/socketpair */
 
 #define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
@@ -387,6 +388,7 @@
 extern int audit_bprm(struct linux_binprm *bprm);
 extern int audit_socketcall(int nargs, unsigned long *args);
 extern int audit_sockaddr(int len, void *addr);
+extern int __audit_fd_pair(int fd1, int fd2);
 extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
 extern int audit_set_macxattr(const char *name);
 extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr);
@@ -401,6 +403,12 @@
 		return __audit_ipc_obj(ipcp);
 	return 0;
 }
+static inline int audit_fd_pair(int fd1, int fd2)
+{
+	if (unlikely(!audit_dummy_context()))
+		return __audit_fd_pair(fd1, fd2);
+	return 0;
+}
 static inline int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
 {
 	if (unlikely(!audit_dummy_context()))
@@ -459,6 +467,7 @@
 #define audit_ipc_set_perm(q,u,g,m) ({ 0; })
 #define audit_bprm(p) ({ 0; })
 #define audit_socketcall(n,a) ({ 0; })
+#define audit_fd_pair(n,a) ({ 0; })
 #define audit_sockaddr(len, addr) ({ 0; })
 #define audit_avc_path(dentry, mnt) ({ 0; })
 #define audit_set_macxattr(n) do { ; } while (0)
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index 047567d..9fa0983 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -33,6 +33,9 @@
 
 struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
 
+struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
+				      const char *dest);
+
 void debugfs_remove(struct dentry *dentry);
 
 struct dentry *debugfs_create_u8(const char *name, mode_t mode,
@@ -70,6 +73,13 @@
 	return ERR_PTR(-ENODEV);
 }
 
+static inline struct dentry *debugfs_create_symlink(const char *name,
+						    struct dentry *parent,
+						    const char *dest)
+{
+	return ERR_PTR(-ENODEV);
+}
+
 static inline void debugfs_remove(struct dentry *dentry)
 { }
 
diff --git a/include/linux/device.h b/include/linux/device.h
index 26e4692..d1a3a27 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -2,6 +2,7 @@
  * device.h - generic, centralized driver model
  *
  * Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
+ * Copyright (c) 2004-2007 Greg Kroah-Hartman <gregkh@suse.de>
  *
  * This file is released under the GPLv2
  *
@@ -101,7 +102,7 @@
 #define BUS_NOTIFY_UNBIND_DRIVER	0x00000004 /* driver about to be
 						      unbound */
 
-/* driverfs interface for exporting bus attributes */
+/* sysfs interface for exporting bus attributes */
 
 struct bus_attribute {
 	struct attribute	attr;
@@ -146,7 +147,7 @@
 extern struct device_driver *driver_find(const char *name, struct bus_type *bus);
 extern int driver_probe_done(void);
 
-/* driverfs interface for exporting driver attributes */
+/* sysfs interface for exporting driver attributes */
 
 struct driver_attribute {
 	struct attribute	attr;
diff --git a/include/linux/ext4_fs_extents.h b/include/linux/ext4_fs_extents.h
index a41cc24..7eb1d73 100644
--- a/include/linux/ext4_fs_extents.h
+++ b/include/linux/ext4_fs_extents.h
@@ -22,12 +22,12 @@
 #include <linux/ext4_fs.h>
 
 /*
- * With AGRESSIVE_TEST defined, the capacity of index/leaf blocks
+ * With AGGRESSIVE_TEST defined, the capacity of index/leaf blocks
  * becomes very small, so index split, in-depth growing and
  * other hard changes happen much more often.
  * This is for debug purposes only.
  */
-#define AGRESSIVE_TEST_
+#define AGGRESSIVE_TEST_
 
 /*
  * With EXTENTS_STATS defined, the number of blocks and extents
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 04e0fa9..79c0282 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -636,7 +636,6 @@
 	unsigned int	bios_cyl;	/* BIOS/fdisk/LILO number of cyls */
 	unsigned int	cyl;		/* "real" number of cyls */
 	unsigned int	drive_data;	/* use by tuneproc/selectproc */
-	unsigned int	usage;		/* current "open()" count for drive */
 	unsigned int	failures;	/* current failure count */
 	unsigned int	max_failures;	/* maximum allowed failure count */
 	u64		probed_capacity;/* initial reported media capacity (ide-cd only currently) */
@@ -736,23 +735,22 @@
 	int (*ide_dma_end)(ide_drive_t *drive);
 	int (*ide_dma_check)(ide_drive_t *drive);
 	int (*ide_dma_on)(ide_drive_t *drive);
-	int (*ide_dma_off_quietly)(ide_drive_t *drive);
+	void (*dma_off_quietly)(ide_drive_t *drive);
 	int (*ide_dma_test_irq)(ide_drive_t *drive);
-	int (*ide_dma_host_on)(ide_drive_t *drive);
-	int (*ide_dma_host_off)(ide_drive_t *drive);
+	void (*ide_dma_clear_irq)(ide_drive_t *drive);
+	void (*dma_host_on)(ide_drive_t *drive);
+	void (*dma_host_off)(ide_drive_t *drive);
 	int (*ide_dma_lostirq)(ide_drive_t *drive);
 	int (*ide_dma_timeout)(ide_drive_t *drive);
 
 	void (*OUTB)(u8 addr, unsigned long port);
 	void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port);
 	void (*OUTW)(u16 addr, unsigned long port);
-	void (*OUTL)(u32 addr, unsigned long port);
 	void (*OUTSW)(unsigned long port, void *addr, u32 count);
 	void (*OUTSL)(unsigned long port, void *addr, u32 count);
 
 	u8  (*INB)(unsigned long port);
 	u16 (*INW)(unsigned long port);
-	u32 (*INL)(unsigned long port);
 	void (*INSW)(unsigned long port, void *addr, u32 count);
 	void (*INSL)(unsigned long port, void *addr, u32 count);
 
@@ -774,7 +772,6 @@
 	unsigned int cursg;
 	unsigned int cursg_ofs;
 
-	int		mmio;		/* hosts iomio (0) or custom (2) select */
 	int		rqsize;		/* max sectors per request */
 	int		irq;		/* our irq number */
 
@@ -802,12 +799,11 @@
 	unsigned	udma_four  : 1;	/* 1=ATA-66 capable, 0=default */
 	unsigned	no_lba48   : 1; /* 1 = cannot do LBA48 */
 	unsigned	no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */
-	unsigned	no_dsc     : 1;	/* 0 default, 1 dsc_overlap disabled */
 	unsigned	auto_poll  : 1; /* supports nop auto-poll */
 	unsigned	sg_mapped  : 1;	/* sg_table and sg_nents are ready */
 	unsigned	no_io_32bit : 1; /* 1 = can not do 32-bit IO ops */
 	unsigned	err_stops_fifo : 1; /* 1=data FIFO is cleared by an error */
-	unsigned	atapi_irq_bogon : 1; /* Generates spurious DMA interrupts in PIO mode */
+	unsigned	mmio       : 1; /* host uses MMIO */
 
 	struct device	gendev;
 	struct completion gendev_rel_comp; /* To deal with device release() */
@@ -1280,8 +1276,9 @@
 int __ide_dma_bad_drive(ide_drive_t *);
 int __ide_dma_good_drive(ide_drive_t *);
 int ide_use_dma(ide_drive_t *);
-int __ide_dma_off(ide_drive_t *);
+void ide_dma_off(ide_drive_t *);
 void ide_dma_verbose(ide_drive_t *);
+int ide_set_dma(ide_drive_t *);
 ide_startstop_t ide_dma_intr(ide_drive_t *);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
@@ -1291,9 +1288,9 @@
 extern int ide_release_dma(ide_hwif_t *);
 extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int);
 
-extern int __ide_dma_host_off(ide_drive_t *);
-extern int __ide_dma_off_quietly(ide_drive_t *);
-extern int __ide_dma_host_on(ide_drive_t *);
+void ide_dma_host_off(ide_drive_t *);
+void ide_dma_off_quietly(ide_drive_t *);
+void ide_dma_host_on(ide_drive_t *);
 extern int __ide_dma_on(ide_drive_t *);
 extern int __ide_dma_check(ide_drive_t *);
 extern int ide_dma_setup(ide_drive_t *);
@@ -1305,8 +1302,9 @@
 
 #else
 static inline int ide_use_dma(ide_drive_t *drive) { return 0; }
-static inline int __ide_dma_off(ide_drive_t *drive) { return 0; }
+static inline void ide_dma_off(ide_drive_t *drive) { ; }
 static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
+static inline int ide_set_dma(ide_drive_t *drive) { return 1; }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
 #ifndef CONFIG_BLK_DEV_IDEDMA_PCI
@@ -1354,6 +1352,7 @@
 extern char *ide_xfer_verbose(u8 xfer_rate);
 extern void ide_toggle_bounce(ide_drive_t *drive, int on);
 extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate);
+int ide_use_fast_pio(ide_drive_t *);
 
 u8 ide_dump_status(ide_drive_t *, const char *, u8);
 
@@ -1367,7 +1366,6 @@
 	u8 pio_mode;
 	u8 use_iordy;
 	u8 overridden;
-	u8 blacklisted;
 	unsigned int cycle_time;
 } ide_pio_data_t;
 
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index e5ea141..838cf5a 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -423,4 +423,13 @@
 extern unsigned int probe_irq_mask(unsigned long);	/* returns mask of ISA interrupts */
 #endif
 
+#ifdef CONFIG_PROC_FS
+/* Initialize /proc/irq/ */
+extern void init_irq_proc(void);
+#else
+static inline void init_irq_proc(void)
+{
+}
+#endif
+
 #endif
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 1939d42..aa5b3e61 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -328,9 +328,6 @@
 /* Resending of interrupts :*/
 void check_irq_resend(struct irq_desc *desc, unsigned int irq);
 
-/* Initialize /proc/irq/ */
-extern void init_irq_proc(void);
-
 /* Enable/disable irq debugging output: */
 extern int noirqdebug_setup(char *str);
 
diff --git a/include/linux/jffs.h b/include/linux/jffs.h
deleted file mode 100644
index 9221321..0000000
--- a/include/linux/jffs.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * JFFS -- Journalling Flash File System, Linux implementation.
- *
- * Copyright (C) 1999, 2000  Axis Communications AB.
- *
- * Created by Finn Hakansson <finn@axis.com>.
- *
- * This 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.
- *
- * $Id: jffs.h,v 1.20 2001/09/18 21:33:37 dwmw2 Exp $
- *
- * Ported to Linux 2.3.x and MTD:
- * Copyright (C) 2000  Alexander Larsson (alex@cendio.se), Cendio Systems AB
- *
- */
-
-#ifndef __LINUX_JFFS_H__
-#define __LINUX_JFFS_H__
-
-#include <linux/types.h>
-#include <linux/completion.h>
-
-#define JFFS_VERSION_STRING "1.0"
-
-/* This is a magic number that is used as an identification number for
-   this file system.  It is written to the super_block structure.  */
-#define JFFS_MAGIC_SB_BITMASK 0x07c0  /* 1984 */
-
-/* This is a magic number that every on-flash raw inode begins with.  */
-#define JFFS_MAGIC_BITMASK 0x34383931 /* "1984" */
-
-/* These two bitmasks are the valid ones for the flash memories we have
-   for the moment.  */
-#define JFFS_EMPTY_BITMASK 0xffffffff
-#define JFFS_DIRTY_BITMASK 0x00000000
-
-/* This is the inode number of the root node.  */
-#define JFFS_MIN_INO 1
-
-/* How many slots in the file hash table should we have?  */
-#define JFFS_HASH_SIZE 40
-
-/* Don't use more than 254 bytes as the maximum allowed length of a file's
-   name due to errors that could occur during the scanning of the flash
-   memory. In fact, a name length of 255 or 0xff, could be the result of
-   an uncompleted write.  For instance, if a raw inode is written to the
-   flash memory and there is a power lossage just before the length of
-   the name is written, the length 255 would be interpreted as an illegal
-   value.  */
-#define JFFS_MAX_NAME_LEN 254
-
-/* Commands for ioctl().  */
-#define JFFS_IOCTL_MAGIC 't'
-#define JFFS_PRINT_HASH _IO(JFFS_IOCTL_MAGIC, 90)
-#define JFFS_PRINT_TREE _IO(JFFS_IOCTL_MAGIC, 91)
-#define JFFS_GET_STATUS _IO(JFFS_IOCTL_MAGIC, 92)
-
-/* XXX: This is something that we should try to get rid of in the future.  */
-#define JFFS_MODIFY_INODE 0x01
-#define JFFS_MODIFY_NAME  0x02
-#define JFFS_MODIFY_DATA  0x04
-#define JFFS_MODIFY_EXIST 0x08
-
-struct jffs_control;
-
-/* The JFFS raw inode structure: Used for storage on physical media.  */
-/* Perhaps the uid, gid, atime, mtime and ctime members should have
-   more space due to future changes in the Linux kernel. Anyhow, since
-   a user of this filesystem probably have to fix a large number of
-   other things, we have decided to not be forward compatible.  */
-struct jffs_raw_inode
-{
-	__u32 magic;      /* A constant magic number.  */
-	__u32 ino;        /* Inode number.  */
-	__u32 pino;       /* Parent's inode number.  */
-	__u32 version;    /* Version number.  */
-	__u32 mode;       /* The file's type or mode.  */
-	__u16 uid;        /* The file's owner.  */
-	__u16 gid;        /* The file's group.  */
-	__u32 atime;      /* Last access time.  */
-	__u32 mtime;      /* Last modification time.  */
-	__u32 ctime;      /* Creation time.  */
-	__u32 offset;     /* Where to begin to write.  */
-	__u32 dsize;      /* Size of the node's data.  */
-	__u32 rsize;      /* How much are going to be replaced?  */
-	__u8 nsize;       /* Name length.  */
-	__u8 nlink;       /* Number of links.  */
-	__u8 spare : 6;   /* For future use.  */
-	__u8 rename : 1;  /* Rename to a name of an already existing file?  */
-	__u8 deleted : 1; /* Has this file been deleted?  */
-	__u8 accurate;    /* The inode is obsolete if accurate == 0.  */
-	__u32 dchksum;    /* Checksum for the data.  */
-	__u16 nchksum;    /* Checksum for the name.  */
-	__u16 chksum;     /* Checksum for the raw inode.  */
-};
-
-/* Define the offset of the accurate byte in struct jffs_raw_inode.  */
-#define JFFS_RAW_INODE_ACCURATE_OFFSET (sizeof(struct jffs_raw_inode) \
-					- 2 * sizeof(__u32) - sizeof(__u8))
-
-/* Define the offset of the chksum member in struct jffs_raw_inode.  */
-#define JFFS_RAW_INODE_CHKSUM_OFFSET (sizeof(struct jffs_raw_inode) \
-				      - sizeof(__u16))
-
-/* Define the offset of the dchksum member in struct jffs_raw_inode.  */
-#define JFFS_RAW_INODE_DCHKSUM_OFFSET (sizeof(struct jffs_raw_inode)   \
-				       - sizeof(__u16) - sizeof(__u16) \
-				       - sizeof(__u32))
-
-
-/* The RAM representation of the node.  The names of pointers to
-   jffs_nodes are very often just called `n' in the source code.  */
-struct jffs_node
-{
-	__u32 ino;          /* Inode number.  */
-	__u32 version;      /* Version number.  */
-	__u32 data_offset;  /* Logic location of the data to insert.  */
-	__u32 data_size;    /* The amount of data this node inserts.  */
-	__u32 removed_size; /* The amount of data that this node removes.  */
-	__u32 fm_offset;    /* Physical location of the data in the actual
-			       flash memory data chunk.  */
-	__u8 name_size;     /* Size of the name.  */
-	struct jffs_fm *fm; /* Physical memory information.  */
-	struct jffs_node *version_prev;
-	struct jffs_node *version_next;
-	struct jffs_node *range_prev;
-	struct jffs_node *range_next;
-};
-
-
-/* The RAM representation of a file (plain files, directories,
-   links, etc.).  Pointers to jffs_files are normally named `f'
-   in the JFFS source code.  */
-struct jffs_file
-{
-	__u32 ino;    /* Inode number.  */
-	__u32 pino;   /* Parent's inode number.  */
-	__u32 mode;   /* file_type, mode  */
-	__u16 uid;    /* owner  */
-	__u16 gid;    /* group  */
-	__u32 atime;  /* Last access time.  */
-	__u32 mtime;  /* Last modification time.  */
-	__u32 ctime;  /* Creation time.  */
-	__u8 nsize;   /* Name length.  */
-	__u8 nlink;   /* Number of links.  */
-	__u8 deleted; /* Has this file been deleted?  */
-	char *name;   /* The name of this file; NULL-terminated.  */
-	__u32 size;   /* The total size of the file's data.  */
-	__u32 highest_version; /* The highest version number of this file.  */
-	struct jffs_control *c;
-	struct jffs_file *parent;   /* Reference to the parent directory.  */
-	struct jffs_file *children; /* Always NULL for plain files.  */
-	struct jffs_file *sibling_prev; /* Siblings in the same directory.  */
-	struct jffs_file *sibling_next;
-	struct list_head hash;    /* hash list.  */
-	struct jffs_node *range_head;   /* The final data.  */
-	struct jffs_node *range_tail;   /* The first data.  */
-	struct jffs_node *version_head; /* The youngest node.  */
-	struct jffs_node *version_tail; /* The oldest node.  */
-};
-
-
-/* This is just a definition of a simple list used for keeping track of
-   files deleted due to a rename.  This list is only used during the
-   mounting of the file system and only if there have been rename operations
-   earlier.  */
-struct jffs_delete_list
-{
-	__u32 ino;
-	struct jffs_delete_list *next;
-};
-
-
-/* A struct for the overall file system control.  Pointers to
-   jffs_control structs are named `c' in the source code.  */
-struct jffs_control
-{
-	struct super_block *sb;		/* Reference to the VFS super block.  */
-	struct jffs_file *root;		/* The root directory file.  */
-	struct list_head *hash;		/* Hash table for finding files by ino.  */
-	struct jffs_fmcontrol *fmc;	/* Flash memory control structure.  */
-	__u32 hash_len;			/* The size of the hash table.  */
-	__u32 next_ino;			/* Next inode number to use for new files.  */
-	__u16 building_fs;		/* Is the file system being built right now?  */
-	struct jffs_delete_list *delete_list; /* Track deleted files.  */
-	pid_t thread_pid;		/* GC thread's PID */
-	struct task_struct *gc_task;	/* GC task struct */
-	struct completion gc_thread_comp; /* GC thread exit mutex */
-	__u32 gc_minfree_threshold;	/* GC trigger thresholds */
-	__u32 gc_maxdirty_threshold;
-};
-
-
-/* Used to inform about flash status.  */
-struct jffs_flash_status
-{
-	__u32 size;
-	__u32 used;
-	__u32 dirty;
-	__u32 begin;
-	__u32 end;
-};
-
-/* This stuff could be used for finding memory leaks.  */
-#define JFFS_MEMORY_DEBUG 0
-
-extern long no_jffs_node;
-#if defined(JFFS_MEMORY_DEBUG) && JFFS_MEMORY_DEBUG
-extern long no_jffs_control;
-extern long no_jffs_raw_inode;
-extern long no_jffs_node_ref;
-extern long no_jffs_fm;
-extern long no_jffs_fmcontrol;
-extern long no_hash;
-extern long no_name;
-#define DJM(x) x
-#else
-#define DJM(x)
-#endif
-
-#endif /* __LINUX_JFFS_H__ */
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index d02425c..696e5ec 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -125,6 +125,7 @@
 #define KEXEC_ARCH_PPC     (20 << 16)
 #define KEXEC_ARCH_PPC64   (21 << 16)
 #define KEXEC_ARCH_IA_64   (50 << 16)
+#define KEXEC_ARCH_ARM     (40 << 16)
 #define KEXEC_ARCH_S390    (22 << 16)
 #define KEXEC_ARCH_SH      (42 << 16)
 #define KEXEC_ARCH_MIPS_LE (10 << 16)
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 10f505c..cc8e674 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -28,8 +28,10 @@
 #ifdef CONFIG_KMOD
 /* modprobe exit status on success, -ve on error.  Return value
  * usually useless though. */
+extern void kmod_sysfs_init(void);
 extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2)));
 #else
+static inline void kmod_sysfs_init(void) {};
 static inline int request_module(const char * name, ...) { return -ENOSYS; }
 #endif
 
diff --git a/include/linux/libata.h b/include/linux/libata.h
index b870b20..86762a9 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -35,6 +35,7 @@
 #include <linux/ata.h>
 #include <linux/workqueue.h>
 #include <scsi/scsi_host.h>
+#include <linux/acpi.h>
 
 /*
  * Define if arch has non-standard setup.  This is a _PCI_ standard
@@ -495,6 +496,10 @@
 	/* error history */
 	struct ata_ering	ering;
 	unsigned int		horkage;	/* List of broken features */
+#ifdef CONFIG_SATA_ACPI
+	/* ACPI objects info */
+	acpi_handle obj_handle;
+#endif
 };
 
 /* Offset into struct ata_device.  Fields above it are maintained
diff --git a/include/linux/log2.h b/include/linux/log2.h
index 99922be..57e641e 100644
--- a/include/linux/log2.h
+++ b/include/linux/log2.h
@@ -152,7 +152,7 @@
  * roundup_pow_of_two - round the given value up to nearest power of two
  * @n - parameter
  *
- * round the given balue up to the nearest power of two
+ * round the given value up to the nearest power of two
  * - the result is undefined when n == 0
  * - this can be used to initialise global variables from constant data
  */
diff --git a/include/linux/module.h b/include/linux/module.h
index 419d3ef..95679eb 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -76,8 +76,6 @@
 		  struct exception_table_entry *finish);
 void sort_main_extable(void);
 
-extern struct subsystem module_subsys;
-
 #ifdef MODULE
 #define MODULE_GENERIC_TABLE(gtype,name)			\
 extern const struct gtype##_id __mod_##gtype##_table		\
@@ -467,10 +465,6 @@
 
 extern void print_modules(void);
 
-struct device_driver;
-void module_add_driver(struct module *, struct device_driver *);
-void module_remove_driver(struct device_driver *);
-
 #else /* !CONFIG_MODULES... */
 #define EXPORT_SYMBOL(sym)
 #define EXPORT_SYMBOL_GPL(sym)
@@ -568,18 +562,59 @@
 {
 }
 
+#endif /* CONFIG_MODULES */
+
 struct device_driver;
+#ifdef CONFIG_SYSFS
 struct module;
 
-static inline void module_add_driver(struct module *module, struct device_driver *driver)
+extern struct subsystem module_subsys;
+
+int mod_sysfs_init(struct module *mod);
+int mod_sysfs_setup(struct module *mod,
+			   struct kernel_param *kparam,
+			   unsigned int num_params);
+int module_add_modinfo_attrs(struct module *mod);
+void module_remove_modinfo_attrs(struct module *mod);
+
+#else /* !CONFIG_SYSFS */
+
+static inline int mod_sysfs_init(struct module *mod)
 {
+	return 0;
 }
 
-static inline void module_remove_driver(struct device_driver *driver)
+static inline int mod_sysfs_setup(struct module *mod,
+			   struct kernel_param *kparam,
+			   unsigned int num_params)
 {
+	return 0;
 }
 
-#endif /* CONFIG_MODULES */
+static inline int module_add_modinfo_attrs(struct module *mod)
+{
+	return 0;
+}
+
+static inline void module_remove_modinfo_attrs(struct module *mod)
+{ }
+
+#endif /* CONFIG_SYSFS */
+
+#if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES)
+
+void module_add_driver(struct module *mod, struct device_driver *drv);
+void module_remove_driver(struct device_driver *drv);
+
+#else /* not both CONFIG_SYSFS && CONFIG_MODULES */
+
+static inline void module_add_driver(struct module *mod, struct device_driver *drv)
+{ }
+
+static inline void module_remove_driver(struct device_driver *drv)
+{ }
+
+#endif
 
 #define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)
 
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index 4a189da..c83588c 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -59,7 +59,7 @@
 };
 
 /* This is the fundamental function for registering boot/module
-   parameters.  perm sets the visibility in driverfs: 000 means it's
+   parameters.  perm sets the visibility in sysfs: 000 means it's
    not there, read bits mean it's readable, write bits mean it's
    writable. */
 #define __module_param_call(prefix, name, set, get, arg, perm)		\
@@ -169,10 +169,22 @@
 
 struct module;
 
+#if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES)
 extern int module_param_sysfs_setup(struct module *mod,
 				    struct kernel_param *kparam,
 				    unsigned int num_params);
 
 extern void module_param_sysfs_remove(struct module *mod);
+#else
+static inline int module_param_sysfs_setup(struct module *mod,
+			     struct kernel_param *kparam,
+			     unsigned int num_params)
+{
+	return 0;
+}
+
+static inline void module_param_sysfs_remove(struct module *mod)
+{ }
+#endif
 
 #endif /* _LINUX_MODULE_PARAMS_H */
diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
index 1221b7c..fff8c53 100644
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -92,6 +92,13 @@
  */
 #define ONENAND_BADBLOCK_POS	0
 
+/*
+ * Bad block scanning errors
+ */
+#define ONENAND_BBT_READ_ERROR		1
+#define ONENAND_BBT_READ_ECC_ERROR	2
+#define ONENAND_BBT_READ_FATAL_ERROR	4
+
 /**
  * struct bbm_info - [GENERIC] Bad Block Table data structure
  * @bbt_erase_shift:	[INTERN] number of address bits in a bbt entry
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 28d461d..81f3a31 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -183,7 +183,7 @@
 struct map_info {
 	char *name;
 	unsigned long size;
-	unsigned long phys;
+	resource_size_t phys;
 #define NO_XIP (-1UL)
 
 	void __iomem *virt;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index d644e57..6a8570b 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -85,6 +85,10 @@
  *		mode = MTD_OOB_PLACE)
  * @datbuf:	data buffer - if NULL only oob data are read/written
  * @oobbuf:	oob data buffer
+ *
+ * Note, it is allowed to read more then one OOB area at one go, but not write.
+ * The interface assumes that the OOB write requests program only one page's
+ * OOB area.
  */
 struct mtd_oob_ops {
 	mtd_oob_mode_t	mode;
@@ -117,18 +121,6 @@
 	u_int32_t writesize;
 
 	u_int32_t oobsize;   // Amount of OOB data per block (e.g. 16)
-	u_int32_t ecctype;
-	u_int32_t eccsize;
-
-	/*
-	 * Reuse some of the above unused fields in the case of NOR flash
-	 * with configurable programming regions to avoid modifying the
-	 * user visible structure layout/size.  Only valid when the
-	 * MTD_PROGRAM_REGIONS flag is set.
-	 * (Maybe we should have an union for those?)
-	 */
-#define MTD_PROGREGION_CTRLMODE_VALID(mtd)  (mtd)->oobsize
-#define MTD_PROGREGION_CTRLMODE_INVALID(mtd)  (mtd)->ecctype
 
 	// Kernel-only stuff starts here.
 	char *name;
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 2071b02..9752388 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -343,6 +343,7 @@
  * @options:		[BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about
  *			special functionality. See the defines for further explanation
  * @badblockpos:	[INTERN] position of the bad block marker in the oob area
+ * @cellinfo:		[INTERN] MLC/multichip data from chip ident
  * @numchips:		[INTERN] number of physical chips
  * @chipsize:		[INTERN] the size of one chip for multichip arrays
  * @pagemask:		[INTERN] page number mask = number of (pages / chip) - 1
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index f775a7a..d8af8a9 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -1,7 +1,7 @@
 /*
  *  linux/include/linux/mtd/onenand.h
  *
- *  Copyright (C) 2005-2006 Samsung Electronics
+ *  Copyright (C) 2005-2007 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -42,14 +42,10 @@
 
 /**
  * struct onenand_bufferram - OneNAND BufferRAM Data
- * @block:		block address in BufferRAM
- * @page:		page address in BufferRAM
- * @valid:		valid flag
+ * @blockpage:		block & page address in BufferRAM
  */
 struct onenand_bufferram {
-	int block;
-	int page;
-	int valid;
+	int	blockpage;
 };
 
 /**
@@ -63,7 +59,6 @@
  *			partly be set to inform onenand_scan about
  * @erase_shift:	[INTERN] number of address bits in a block
  * @page_shift:		[INTERN] number of address bits in a page
- * @ppb_shift:		[INTERN] number of address bits in a pages per block
  * @page_mask:		[INTERN] a page per block mask
  * @bufferram_index:	[INTERN] BufferRAM index
  * @bufferram:		[INTERN] BufferRAM info
@@ -103,7 +98,6 @@
 
 	unsigned int		erase_shift;
 	unsigned int		page_shift;
-	unsigned int		ppb_shift;	/* Pages per block shift */
 	unsigned int		page_mask;
 
 	unsigned int		bufferram_index;
@@ -150,6 +144,9 @@
 #define ONENAND_SET_SYS_CFG1(v, this)					\
 	(this->write_word(v, this->base + ONENAND_REG_SYS_CFG1))
 
+#define ONENAND_IS_DDP(this)						\
+	(this->device_id & ONENAND_DEVICE_IS_DDP)
+
 /* Check byte access in OneNAND */
 #define ONENAND_CHECK_BYTE_ACCESS(addr)		(addr & 0x1)
 
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
index e31c8f5..af94719 100644
--- a/include/linux/mtd/onenand_regs.h
+++ b/include/linux/mtd/onenand_regs.h
@@ -3,7 +3,8 @@
  *
  *  OneNAND Register header file
  *
- *  Copyright (C) 2005-2006 Samsung Electronics
+ *  Copyright (C) 2005-2007 Samsung Electronics
+ *  Kyungmin Park <kyungmin.park@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -80,9 +81,11 @@
 #define ONENAND_VERSION_PROCESS_SHIFT	(8)
 
 /*
- * Start Address 1 F100h (R/W)
+ * Start Address 1 F100h (R/W) & Start Address 2 F101h (R/W)
  */
 #define ONENAND_DDP_SHIFT		(15)
+#define ONENAND_DDP_CHIP0		(0)
+#define ONENAND_DDP_CHIP1		(1 << ONENAND_DDP_SHIFT)
 
 /*
  * Start Address 8 F107h (R/W)
diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h
index 86831e3..0dc07d5 100644
--- a/include/linux/mtd/physmap.h
+++ b/include/linux/mtd/physmap.h
@@ -18,9 +18,10 @@
 #define __LINUX_MTD_PHYSMAP__
 
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
 
+struct map_info;
+
 struct physmap_flash_data {
 	unsigned int		width;
 	void			(*set_vpp)(struct map_info *, int);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 98c8765..2c4b684 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -854,5 +854,8 @@
 #define PCIPCI_ALIMAGIK		32	/* Need low latency setting */
 #define PCIAGP_FAIL		64	/* No PCI to AGP DMA */
 
+extern unsigned long pci_cardbus_io_size;
+extern unsigned long pci_cardbus_mem_size;
+
 #endif /* __KERNEL__ */
 #endif /* LINUX_PCI_H */
diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
index 6b0648c..52c9eb9 100644
--- a/include/linux/seqlock.h
+++ b/include/linux/seqlock.h
@@ -2,7 +2,7 @@
 #define __LINUX_SEQLOCK_H
 /*
  * Reader/writer consistent mechanism without starving writers. This type of
- * lock for data where the reader wants a consitent set of information
+ * lock for data where the reader wants a consistent set of information
  * and is willing to retry if the information changes.  Readers never
  * block but they may have to retry if a writer is in
  * progress. Writers do not wait for readers. 
diff --git a/include/linux/serio.h b/include/linux/serio.h
index ac2c70e..1ebf045 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -108,12 +108,6 @@
 		serio->drv->write_wakeup(serio);
 }
 
-static inline void serio_cleanup(struct serio *serio)
-{
-	if (serio->drv && serio->drv->cleanup)
-		serio->drv->cleanup(serio);
-}
-
 /*
  * Use the following functions to manipulate serio's per-port
  * driver-specific data.
diff --git a/include/linux/usb.h b/include/linux/usb.h
index b5c226a..a8e8d1e 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -935,7 +935,7 @@
 	unsigned int offset;
 	unsigned int length;		/* expected length */
 	unsigned int actual_length;
-	unsigned int status;
+	int status;
 };
 
 struct urb;
diff --git a/include/linux/usb/cdc.h b/include/linux/usb/cdc.h
index ba617c3..956edf3 100644
--- a/include/linux/usb/cdc.h
+++ b/include/linux/usb/cdc.h
@@ -73,6 +73,13 @@
 	__u8	bmCapabilities;
 } __attribute__ ((packed));
 
+/* capabilities from 5.2.3.3 */
+
+#define USB_CDC_COMM_FEATURE	0x01
+#define USB_CDC_CAP_LINE	0x02
+#define USB_CDC_CAP_BRK	0x04
+#define USB_CDC_CAP_NOTIFY	0x08
+
 /* "Union Functional Descriptor" from CDC spec 5.2.3.8 */
 struct usb_cdc_union_desc {
 	__u8	bLength;
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index ae78337..245c725 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -367,7 +367,7 @@
 	/* bulk endpoints with 8 byte maxpacket */
 	__u8  bDebugInEndpoint;
 	__u8  bDebugOutEndpoint;
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -396,7 +396,7 @@
 
 	__le16 wTotalLength;
 	__u8  bNumEncryptionTypes;
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -410,7 +410,7 @@
 	__u8  tTKID[3];
 	__u8  bReserved;
 	__u8  bKeyData[0];
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -426,7 +426,7 @@
 #define	USB_ENC_TYPE_RSA_1		3	/* rsa3072/sha1 auth */
 	__u8  bEncryptionValue;		/* use in SET_ENCRYPTION */
 	__u8  bAuthKeyIndex;
-};
+} __attribute__((packed));
 
 
 /*-------------------------------------------------------------------------*/
@@ -438,7 +438,7 @@
 
 	__le16 wTotalLength;
 	__u8  bNumDeviceCaps;
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -447,7 +447,7 @@
 	__u8  bLength;
 	__u8  bDescriptorType;
 	__u8  bDevCapabilityType;
-};
+} __attribute__((packed));
 
 #define	USB_CAP_TYPE_WIRELESS_USB	1
 
@@ -475,7 +475,7 @@
 	__u8  bmFFITXPowerInfo;	/* FFI power levels */
 	__le16 bmBandGroup;
 	__u8  bReserved;
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -496,7 +496,7 @@
 #define USB_ENDPOINT_SWITCH_NO		0
 #define USB_ENDPOINT_SWITCH_SWITCH	1
 #define USB_ENDPOINT_SWITCH_SCALE	2
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -512,7 +512,7 @@
 	__u8 CDID[16];
 	__u8 nonce[16];
 	__u8 MIC[8];
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -524,7 +524,7 @@
 	__u8 CHID[16];		/* persistent host id */
 	__u8 CDID[16];		/* device id (unique w/in host context) */
 	__u8 CK[16];		/* connection key */
-};
+} __attribute__((packed));
 
 /*-------------------------------------------------------------------------*/
 
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 33dcd85..32acbae 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -54,6 +54,8 @@
  * @write_wait: a wait_queue_head_t used by the port.
  * @work: work queue entry for the line discipline waking up.
  * @open_count: number of times this port has been opened.
+ * @throttled: nonzero if the read urb is inactive to throttle the device
+ * @throttle_req: nonzero if the tty wants to throttle us
  *
  * This structure is used by the usb-serial core and drivers for the specific
  * ports of a device.
@@ -88,6 +90,8 @@
 	wait_queue_head_t	write_wait;
 	struct work_struct	work;
 	int			open_count;
+	char			throttled;
+	char			throttle_req;
 	struct device		dev;
 };
 #define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev)
@@ -269,6 +273,8 @@
 extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port);
 extern void usb_serial_generic_read_bulk_callback (struct urb *urb);
 extern void usb_serial_generic_write_bulk_callback (struct urb *urb);
+extern void usb_serial_generic_throttle (struct usb_serial_port *port);
+extern void usb_serial_generic_unthrottle (struct usb_serial_port *port);
 extern void usb_serial_generic_shutdown (struct usb_serial *serial);
 extern int usb_serial_generic_register (int debug);
 extern void usb_serial_generic_deregister (void);
diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h
index 2ae76fe..1b792b9 100644
--- a/include/linux/usb_usual.h
+++ b/include/linux/usb_usual.h
@@ -46,7 +46,9 @@
 	US_FLAG(MAX_SECTORS_64,	0x00000400)			\
 		/* Sets max_sectors to 64    */			\
 	US_FLAG(IGNORE_DEVICE,	0x00000800)			\
-		/* Don't claim device */
+		/* Don't claim device */			\
+	US_FLAG(CAPACITY_HEURISTICS,	0x00001000)		\
+		/* sometimes sizes is too big */
 
 #define US_FLAG(name, value)	US_FL_##name = value ,
 enum { US_DO_ALL_FLAGS };
diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h
index 617d8a1..342dd5a 100644
--- a/include/linux/usbdevice_fs.h
+++ b/include/linux/usbdevice_fs.h
@@ -159,9 +159,9 @@
 #define USBDEVFS_SUBMITURB32       _IOR('U', 10, struct usbdevfs_urb32)
 #define USBDEVFS_DISCARDURB        _IO('U', 11)
 #define USBDEVFS_REAPURB           _IOW('U', 12, void *)
-#define USBDEVFS_REAPURB32         _IOW('U', 12, u32)
+#define USBDEVFS_REAPURB32         _IOW('U', 12, __u32)
 #define USBDEVFS_REAPURBNDELAY     _IOW('U', 13, void *)
-#define USBDEVFS_REAPURBNDELAY32   _IOW('U', 13, u32)
+#define USBDEVFS_REAPURBNDELAY32   _IOW('U', 13, __u32)
 #define USBDEVFS_DISCSIGNAL        _IOR('U', 14, struct usbdevfs_disconnectsignal)
 #define USBDEVFS_CLAIMINTERFACE    _IOR('U', 15, unsigned int)
 #define USBDEVFS_RELEASEINTERFACE  _IOR('U', 16, unsigned int)
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index f913c30..8e501a7 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -36,12 +36,6 @@
 #define MTD_CAP_NORFLASH	(MTD_WRITEABLE | MTD_BIT_WRITEABLE)
 #define MTD_CAP_NANDFLASH	(MTD_WRITEABLE)
 
-
-// Types of automatic ECC/Checksum available
-#define MTD_ECC_NONE		0 	// No automatic ECC available
-#define MTD_ECC_RS_DiskOnChip	1	// Automatic ECC on DiskOnChip
-#define MTD_ECC_SW		2	// SW ECC for Toshiba & Samsung devices
-
 /* ECC byte placement */
 #define MTD_NANDECC_OFF		0	// Switch off ECC (Not recommended)
 #define MTD_NANDECC_PLACE	1	// Use the given placement in the structure (YAFFS1 legacy mode)
@@ -61,6 +55,8 @@
 	uint32_t erasesize;
 	uint32_t writesize;
 	uint32_t oobsize;   // Amount of OOB data per block (e.g. 16)
+	/* The below two fields are obsolete and broken, do not use them
+	 * (TODO: remove at some point) */
 	uint32_t ecctype;
 	uint32_t eccsize;
 };
diff --git a/include/pcmcia/ciscode.h b/include/pcmcia/ciscode.h
index c1da855..eae7e2e 100644
--- a/include/pcmcia/ciscode.h
+++ b/include/pcmcia/ciscode.h
@@ -95,6 +95,7 @@
 #define PRODID_QUATECH_DUAL_RS232	0x0012
 #define PRODID_QUATECH_DUAL_RS232_D1	0x0007
 #define PRODID_QUATECH_DUAL_RS232_D2	0x0052
+#define PRODID_QUATECH_DUAL_RS232_G	0x004d
 #define PRODID_QUATECH_QUAD_RS232	0x001b
 #define PRODID_QUATECH_DUAL_RS422	0x000e
 #define PRODID_QUATECH_QUAD_RS422	0x0045
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index c094e50..c36750f 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -110,6 +110,12 @@
 	dev_addr->broadcast[9] = (unsigned char) pkey;
 }
 
+static inline void ib_addr_get_mgid(struct rdma_dev_addr *dev_addr,
+				    union ib_gid *gid)
+{
+	memcpy(gid, dev_addr->broadcast + 4, sizeof *gid);
+}
+
 static inline void ib_addr_get_sgid(struct rdma_dev_addr *dev_addr,
 				    union ib_gid *gid)
 {
diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h
index 97715b0..5e26b2f 100644
--- a/include/rdma/ib_sa.h
+++ b/include/rdma/ib_sa.h
@@ -285,18 +285,6 @@
 		       void *context,
 		       struct ib_sa_query **query);
 
-int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
-			     struct ib_device *device, u8 port_num,
-			     u8 method,
-			     struct ib_sa_mcmember_rec *rec,
-			     ib_sa_comp_mask comp_mask,
-			     int timeout_ms, gfp_t gfp_mask,
-			     void (*callback)(int status,
-					      struct ib_sa_mcmember_rec *resp,
-					      void *context),
-			     void *context,
-			     struct ib_sa_query **query);
-
 int ib_sa_service_rec_query(struct ib_sa_client *client,
 			 struct ib_device *device, u8 port_num,
 			 u8 method,
@@ -309,93 +297,82 @@
 			 void *context,
 			 struct ib_sa_query **sa_query);
 
-/**
- * ib_sa_mcmember_rec_set - Start an MCMember set query
- * @client:SA client
- * @device:device to send query on
- * @port_num: port number to send query on
- * @rec:MCMember Record to send in query
- * @comp_mask:component mask to send in query
- * @timeout_ms:time to wait for response
- * @gfp_mask:GFP mask to use for internal allocations
- * @callback:function called when query completes, times out or is
- * canceled
- * @context:opaque user context passed to callback
- * @sa_query:query context, used to cancel query
- *
- * Send an MCMember Set query to the SA (eg to join a multicast
- * group).  The callback function will be called when the query
- * completes (or fails); status is 0 for a successful response, -EINTR
- * if the query is canceled, -ETIMEDOUT is the query timed out, or
- * -EIO if an error occurred sending the query.  The resp parameter of
- * the callback is only valid if status is 0.
- *
- * If the return value of ib_sa_mcmember_rec_set() is negative, it is
- * an error code.  Otherwise it is a query ID that can be used to
- * cancel the query.
- */
-static inline int
-ib_sa_mcmember_rec_set(struct ib_sa_client *client,
-		       struct ib_device *device, u8 port_num,
-		       struct ib_sa_mcmember_rec *rec,
-		       ib_sa_comp_mask comp_mask,
-		       int timeout_ms, gfp_t gfp_mask,
-		       void (*callback)(int status,
-					struct ib_sa_mcmember_rec *resp,
-					void *context),
-		       void *context,
-		       struct ib_sa_query **query)
-{
-	return ib_sa_mcmember_rec_query(client, device, port_num,
-					IB_MGMT_METHOD_SET,
-					rec, comp_mask,
-					timeout_ms, gfp_mask, callback,
-					context, query);
-}
+struct ib_sa_multicast {
+	struct ib_sa_mcmember_rec rec;
+	ib_sa_comp_mask		comp_mask;
+	int			(*callback)(int status,
+					    struct ib_sa_multicast *multicast);
+	void			*context;
+};
 
 /**
- * ib_sa_mcmember_rec_delete - Start an MCMember delete query
- * @client:SA client
- * @device:device to send query on
- * @port_num: port number to send query on
- * @rec:MCMember Record to send in query
- * @comp_mask:component mask to send in query
- * @timeout_ms:time to wait for response
- * @gfp_mask:GFP mask to use for internal allocations
- * @callback:function called when query completes, times out or is
- * canceled
- * @context:opaque user context passed to callback
- * @sa_query:query context, used to cancel query
+ * ib_sa_join_multicast - Initiates a join request to the specified multicast
+ *   group.
+ * @client: SA client
+ * @device: Device associated with the multicast group.
+ * @port_num: Port on the specified device to associate with the multicast
+ *   group.
+ * @rec: SA multicast member record specifying group attributes.
+ * @comp_mask: Component mask indicating which group attributes of %rec are
+ *   valid.
+ * @gfp_mask: GFP mask for memory allocations.
+ * @callback: User callback invoked once the join operation completes.
+ * @context: User specified context stored with the ib_sa_multicast structure.
  *
- * Send an MCMember Delete query to the SA (eg to leave a multicast
- * group).  The callback function will be called when the query
- * completes (or fails); status is 0 for a successful response, -EINTR
- * if the query is canceled, -ETIMEDOUT is the query timed out, or
- * -EIO if an error occurred sending the query.  The resp parameter of
- * the callback is only valid if status is 0.
+ * This call initiates a multicast join request with the SA for the specified
+ * multicast group.  If the join operation is started successfully, it returns
+ * an ib_sa_multicast structure that is used to track the multicast operation.
+ * Users must free this structure by calling ib_free_multicast, even if the
+ * join operation later fails.  (The callback status is non-zero.)
  *
- * If the return value of ib_sa_mcmember_rec_delete() is negative, it
- * is an error code.  Otherwise it is a query ID that can be used to
- * cancel the query.
+ * If the join operation fails; status will be non-zero, with the following
+ * failures possible:
+ * -ETIMEDOUT: The request timed out.
+ * -EIO: An error occurred sending the query.
+ * -EINVAL: The MCMemberRecord values differed from the existing group's.
+ * -ENETRESET: Indicates that an fatal error has occurred on the multicast
+ *   group, and the user must rejoin the group to continue using it.
  */
-static inline int
-ib_sa_mcmember_rec_delete(struct ib_sa_client *client,
-			  struct ib_device *device, u8 port_num,
-			  struct ib_sa_mcmember_rec *rec,
-			  ib_sa_comp_mask comp_mask,
-			  int timeout_ms, gfp_t gfp_mask,
-			  void (*callback)(int status,
-					   struct ib_sa_mcmember_rec *resp,
-					   void *context),
-			  void *context,
-			  struct ib_sa_query **query)
-{
-	return ib_sa_mcmember_rec_query(client, device, port_num,
-					IB_SA_METHOD_DELETE,
-					rec, comp_mask,
-					timeout_ms, gfp_mask, callback,
-					context, query);
-}
+struct ib_sa_multicast *ib_sa_join_multicast(struct ib_sa_client *client,
+					     struct ib_device *device, u8 port_num,
+					     struct ib_sa_mcmember_rec *rec,
+					     ib_sa_comp_mask comp_mask, gfp_t gfp_mask,
+					     int (*callback)(int status,
+							     struct ib_sa_multicast
+								    *multicast),
+					     void *context);
+
+/**
+ * ib_free_multicast - Frees the multicast tracking structure, and releases
+ *    any reference on the multicast group.
+ * @multicast: Multicast tracking structure allocated by ib_join_multicast.
+ *
+ * This call blocks until the multicast identifier is destroyed.  It may
+ * not be called from within the multicast callback; however, returning a non-
+ * zero value from the callback will result in destroying the multicast
+ * tracking structure.
+ */
+void ib_sa_free_multicast(struct ib_sa_multicast *multicast);
+
+/**
+ * ib_get_mcmember_rec - Looks up a multicast member record by its MGID and
+ *   returns it if found.
+ * @device: Device associated with the multicast group.
+ * @port_num: Port on the specified device to associate with the multicast
+ *   group.
+ * @mgid: MGID of multicast group.
+ * @rec: Location to copy SA multicast member record.
+ */
+int ib_sa_get_mcmember_rec(struct ib_device *device, u8 port_num,
+			   union ib_gid *mgid, struct ib_sa_mcmember_rec *rec);
+
+/**
+ * ib_init_ah_from_mcmember - Initialize address handle attributes based on
+ * an SA multicast member record.
+ */
+int ib_init_ah_from_mcmember(struct ib_device *device, u8 port_num,
+			     struct ib_sa_mcmember_rec *rec,
+			     struct ib_ah_attr *ah_attr);
 
 /**
  * ib_init_ah_from_path - Initialize address handle attributes based on an SA
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h
index 36cd8a8..2d6a770 100644
--- a/include/rdma/rdma_cm.h
+++ b/include/rdma/rdma_cm.h
@@ -52,10 +52,13 @@
 	RDMA_CM_EVENT_ESTABLISHED,
 	RDMA_CM_EVENT_DISCONNECTED,
 	RDMA_CM_EVENT_DEVICE_REMOVAL,
+	RDMA_CM_EVENT_MULTICAST_JOIN,
+	RDMA_CM_EVENT_MULTICAST_ERROR
 };
 
 enum rdma_port_space {
 	RDMA_PS_SDP  = 0x0001,
+	RDMA_PS_IPOIB= 0x0002,
 	RDMA_PS_TCP  = 0x0106,
 	RDMA_PS_UDP  = 0x0111,
 	RDMA_PS_SCTP = 0x0183
@@ -294,5 +297,21 @@
  */
 int rdma_disconnect(struct rdma_cm_id *id);
 
-#endif /* RDMA_CM_H */
+/**
+ * rdma_join_multicast - Join the multicast group specified by the given
+ *   address.
+ * @id: Communication identifier associated with the request.
+ * @addr: Multicast address identifying the group to join.
+ * @context: User-defined context associated with the join request, returned
+ * to the user through the private_data pointer in multicast events.
+ */
+int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
+			void *context);
 
+/**
+ * rdma_leave_multicast - Leave the multicast group specified by the given
+ *   address.
+ */
+void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr);
+
+#endif /* RDMA_CM_H */
diff --git a/include/rdma/rdma_cm_ib.h b/include/rdma/rdma_cm_ib.h
index 9b176df..950424b 100644
--- a/include/rdma/rdma_cm_ib.h
+++ b/include/rdma/rdma_cm_ib.h
@@ -44,7 +44,7 @@
 int rdma_set_ib_paths(struct rdma_cm_id *id,
 		      struct ib_sa_path_rec *path_rec, int num_paths);
 
-/* Global qkey for UD QPs and multicast groups. */
-#define RDMA_UD_QKEY 0x01234567
+/* Global qkey for UDP QPs and multicast groups. */
+#define RDMA_UDP_QKEY 0x01234567
 
 #endif /* RDMA_CM_IB_H */
diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h
index 9572ab8..f632b0c 100644
--- a/include/rdma/rdma_user_cm.h
+++ b/include/rdma/rdma_user_cm.h
@@ -38,7 +38,7 @@
 #include <rdma/ib_user_verbs.h>
 #include <rdma/ib_user_sa.h>
 
-#define RDMA_USER_CM_ABI_VERSION	3
+#define RDMA_USER_CM_ABI_VERSION	4
 
 #define RDMA_MAX_PRIVATE_DATA		256
 
@@ -58,7 +58,9 @@
 	RDMA_USER_CM_CMD_GET_EVENT,
 	RDMA_USER_CM_CMD_GET_OPTION,
 	RDMA_USER_CM_CMD_SET_OPTION,
-	RDMA_USER_CM_CMD_NOTIFY
+	RDMA_USER_CM_CMD_NOTIFY,
+	RDMA_USER_CM_CMD_JOIN_MCAST,
+	RDMA_USER_CM_CMD_LEAVE_MCAST
 };
 
 /*
@@ -188,6 +190,13 @@
 	__u32 event;
 };
 
+struct rdma_ucm_join_mcast {
+	__u64 response;		/* rdma_ucm_create_id_resp */
+	__u64 uid;
+	struct sockaddr_in6 addr;
+	__u32 id;
+};
+
 struct rdma_ucm_get_event {
 	__u64 response;
 };
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index ebf31b1..9dd37e2 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -122,6 +122,7 @@
 	unsigned no_uld_attach:1; /* disable connecting to upper level drivers */
 	unsigned select_no_atn:1;
 	unsigned fix_capacity:1;	/* READ_CAPACITY is too high by 1 */
+	unsigned guess_capacity:1;	/* READ_CAPACITY might be too high by 1 */
 	unsigned retry_hwerror:1;	/* Retry HARDWARE_ERROR */
 
 	unsigned int device_blocked;	/* Device returned QUEUE_FULL. */
diff --git a/include/scsi/scsi_tgt_if.h b/include/scsi/scsi_tgt_if.h
index 46d5e70..07d6e77 100644
--- a/include/scsi/scsi_tgt_if.h
+++ b/include/scsi/scsi_tgt_if.h
@@ -83,8 +83,5 @@
 } __attribute__ ((aligned (sizeof(uint64_t))));
 
 #define TGT_RING_SIZE (1UL << 16)
-#define TGT_RING_PAGES (TGT_RING_SIZE >> PAGE_SHIFT)
-#define TGT_EVENT_PER_PAGE (PAGE_SIZE / sizeof(struct tgt_event))
-#define TGT_MAX_EVENTS (TGT_EVENT_PER_PAGE * TGT_RING_PAGES)
 
 #endif
diff --git a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h
index cca1d49..3c18baa 100644
--- a/include/scsi/scsi_transport.h
+++ b/include/scsi/scsi_transport.h
@@ -22,6 +22,7 @@
 
 #include <linux/transport_class.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
 
 struct scsi_transport_template {
 	/* the attribute containers */
diff --git a/init/main.c b/init/main.c
index 953500b..1c5f6dc 100644
--- a/init/main.c
+++ b/init/main.c
@@ -41,6 +41,7 @@
 #include <linux/cpuset.h>
 #include <linux/efi.h>
 #include <linux/tick.h>
+#include <linux/interrupt.h>
 #include <linux/taskstats_kern.h>
 #include <linux/delayacct.h>
 #include <linux/unistd.h>
@@ -702,11 +703,7 @@
 	init_workqueues();
 	usermodehelper_init();
 	driver_init();
-
-#ifdef CONFIG_PROC_FS
 	init_irq_proc();
-#endif
-
 	do_initcalls();
 }
 
diff --git a/kernel/audit.c b/kernel/audit.c
index d9b690a..76c9a11 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2,7 +2,7 @@
  * Gateway between the kernel (e.g., selinux) and the user-space audit daemon.
  * System-call specific features have moved to auditsc.c
  *
- * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
+ * Copyright 2003-2007 Red Hat Inc., Durham, North Carolina.
  * All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -65,7 +65,9 @@
  * (Initialization happens after skb_init is called.) */
 static int	audit_initialized;
 
-/* No syscall auditing will take place unless audit_enabled != 0. */
+/* 0 - no auditing
+ * 1 - auditing enabled
+ * 2 - auditing enabled and configuration is locked/unchangeable. */
 int		audit_enabled;
 
 /* Default state when kernel boots without any parameters. */
@@ -239,102 +241,150 @@
 
 static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid)
 {
-	int old	= audit_rate_limit;
+	int res, rc = 0, old = audit_rate_limit;
+
+	/* check if we are locked */
+	if (audit_enabled == 2)
+		res = 0;
+	else
+		res = 1;
 
 	if (sid) {
 		char *ctx = NULL;
 		u32 len;
-		int rc;
-		if ((rc = selinux_sid_to_string(sid, &ctx, &len)))
-			return rc;
-		else
+		if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
 			audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-				"audit_rate_limit=%d old=%d by auid=%u subj=%s",
-				limit, old, loginuid, ctx);
-		kfree(ctx);
-	} else
-		audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-			"audit_rate_limit=%d old=%d by auid=%u",
-			limit, old, loginuid);
-	audit_rate_limit = limit;
-	return 0;
+				"audit_rate_limit=%d old=%d by auid=%u"
+				" subj=%s res=%d",
+				limit, old, loginuid, ctx, res);
+			kfree(ctx);
+		} else
+			res = 0; /* Something weird, deny request */
+	}
+	audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
+		"audit_rate_limit=%d old=%d by auid=%u res=%d",
+		limit, old, loginuid, res);
+
+	/* If we are allowed, make the change */
+	if (res == 1)
+		audit_rate_limit = limit;
+	/* Not allowed, update reason */
+	else if (rc == 0)
+		rc = -EPERM;
+	return rc;
 }
 
 static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid)
 {
-	int old	= audit_backlog_limit;
+	int res, rc = 0, old = audit_backlog_limit;
+
+	/* check if we are locked */
+	if (audit_enabled == 2)
+		res = 0;
+	else
+		res = 1;
 
 	if (sid) {
 		char *ctx = NULL;
 		u32 len;
-		int rc;
-		if ((rc = selinux_sid_to_string(sid, &ctx, &len)))
-			return rc;
-		else
+		if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
 			audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-			    "audit_backlog_limit=%d old=%d by auid=%u subj=%s",
-				limit, old, loginuid, ctx);
-		kfree(ctx);
-	} else
-		audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-			"audit_backlog_limit=%d old=%d by auid=%u",
-			limit, old, loginuid);
-	audit_backlog_limit = limit;
-	return 0;
+				"audit_backlog_limit=%d old=%d by auid=%u"
+				" subj=%s res=%d",
+				limit, old, loginuid, ctx, res);
+			kfree(ctx);
+		} else
+			res = 0; /* Something weird, deny request */
+	}
+	audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
+		"audit_backlog_limit=%d old=%d by auid=%u res=%d",
+		limit, old, loginuid, res);
+
+	/* If we are allowed, make the change */
+	if (res == 1)
+		audit_backlog_limit = limit;
+	/* Not allowed, update reason */
+	else if (rc == 0)
+		rc = -EPERM;
+	return rc;
 }
 
 static int audit_set_enabled(int state, uid_t loginuid, u32 sid)
 {
-	int old = audit_enabled;
+	int res, rc = 0, old = audit_enabled;
 
-	if (state != 0 && state != 1)
+	if (state < 0 || state > 2)
 		return -EINVAL;
 
+	/* check if we are locked */
+	if (audit_enabled == 2)
+		res = 0;
+	else
+		res = 1;
+
 	if (sid) {
 		char *ctx = NULL;
 		u32 len;
-		int rc;
-		if ((rc = selinux_sid_to_string(sid, &ctx, &len)))
-			return rc;
-		else
+		if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
 			audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-				"audit_enabled=%d old=%d by auid=%u subj=%s",
-				state, old, loginuid, ctx);
-		kfree(ctx);
-	} else
-		audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-			"audit_enabled=%d old=%d by auid=%u",
-			state, old, loginuid);
-	audit_enabled = state;
-	return 0;
+				"audit_enabled=%d old=%d by auid=%u"
+				" subj=%s res=%d",
+				state, old, loginuid, ctx, res);
+			kfree(ctx);
+		} else
+			res = 0; /* Something weird, deny request */
+	}
+	audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
+		"audit_enabled=%d old=%d by auid=%u res=%d",
+		state, old, loginuid, res);
+
+	/* If we are allowed, make the change */
+	if (res == 1)
+		audit_enabled = state;
+	/* Not allowed, update reason */
+	else if (rc == 0)
+		rc = -EPERM;
+	return rc;
 }
 
 static int audit_set_failure(int state, uid_t loginuid, u32 sid)
 {
-	int old = audit_failure;
+	int res, rc = 0, old = audit_failure;
 
 	if (state != AUDIT_FAIL_SILENT
 	    && state != AUDIT_FAIL_PRINTK
 	    && state != AUDIT_FAIL_PANIC)
 		return -EINVAL;
 
+	/* check if we are locked */
+	if (audit_enabled == 2)
+		res = 0;
+	else
+		res = 1;
+
 	if (sid) {
 		char *ctx = NULL;
 		u32 len;
-		int rc;
-		if ((rc = selinux_sid_to_string(sid, &ctx, &len)))
-			return rc;
-		else
+		if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
 			audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-				"audit_failure=%d old=%d by auid=%u subj=%s",
-				state, old, loginuid, ctx);
-		kfree(ctx);
-	} else
-		audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-			"audit_failure=%d old=%d by auid=%u",
-			state, old, loginuid);
-	audit_failure = state;
-	return 0;
+				"audit_failure=%d old=%d by auid=%u"
+				" subj=%s res=%d",
+				state, old, loginuid, ctx, res);
+			kfree(ctx);
+		} else
+			res = 0; /* Something weird, deny request */
+	}
+	audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
+		"audit_failure=%d old=%d by auid=%u res=%d",
+		state, old, loginuid, res);
+
+	/* If we are allowed, make the change */
+	if (res == 1)
+		audit_failure = state;
+	/* Not allowed, update reason */
+	else if (rc == 0)
+		rc = -EPERM;
+	return rc;
 }
 
 static int kauditd_thread(void *dummy)
@@ -599,6 +649,30 @@
 	case AUDIT_DEL:
 		if (nlmsg_len(nlh) < sizeof(struct audit_rule))
 			return -EINVAL;
+		if (audit_enabled == 2) {
+			ab = audit_log_start(NULL, GFP_KERNEL,
+					AUDIT_CONFIG_CHANGE);
+			if (ab) {
+				audit_log_format(ab,
+						 "pid=%d uid=%u auid=%u",
+						 pid, uid, loginuid);
+				if (sid) {
+					if (selinux_sid_to_string(
+							sid, &ctx, &len)) {
+						audit_log_format(ab,
+							" ssid=%u", sid);
+						/* Maybe call audit_panic? */
+					} else
+						audit_log_format(ab,
+							" subj=%s", ctx);
+					kfree(ctx);
+				}
+				audit_log_format(ab, " audit_enabled=%d res=0",
+					audit_enabled);
+				audit_log_end(ab);
+			}
+			return -EPERM;
+		}
 		/* fallthrough */
 	case AUDIT_LIST:
 		err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
@@ -609,6 +683,30 @@
 	case AUDIT_DEL_RULE:
 		if (nlmsg_len(nlh) < sizeof(struct audit_rule_data))
 			return -EINVAL;
+		if (audit_enabled == 2) {
+			ab = audit_log_start(NULL, GFP_KERNEL,
+					AUDIT_CONFIG_CHANGE);
+			if (ab) {
+				audit_log_format(ab,
+						 "pid=%d uid=%u auid=%u",
+						 pid, uid, loginuid);
+				if (sid) {
+					if (selinux_sid_to_string(
+							sid, &ctx, &len)) {
+						audit_log_format(ab,
+							" ssid=%u", sid);
+						/* Maybe call audit_panic? */
+					} else
+						audit_log_format(ab,
+							" subj=%s", ctx);
+					kfree(ctx);
+				}
+				audit_log_format(ab, " audit_enabled=%d res=0",
+					audit_enabled);
+				audit_log_end(ab);
+			}
+			return -EPERM;
+		}
 		/* fallthrough */
 	case AUDIT_LIST_RULES:
 		err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 87865f8..3749193 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -937,9 +937,10 @@
 		}
 
 		ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
-		audit_log_format(ab, "audit updated rules specifying path=");
+		audit_log_format(ab, "op=updated rules specifying path=");
 		audit_log_untrustedstring(ab, owatch->path);
 		audit_log_format(ab, " with dev=%u ino=%lu\n", dev, ino);
+		audit_log_format(ab, " list=%d res=1", r->listnr);
 		audit_log_end(ab);
 
 		audit_remove_watch(owatch);
@@ -969,14 +970,14 @@
 			e = container_of(r, struct audit_entry, rule);
 
 			ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
-			audit_log_format(ab, "audit implicitly removed rule path=");
+			audit_log_format(ab, "op=remove rule path=");
 			audit_log_untrustedstring(ab, w->path);
 			if (r->filterkey) {
 				audit_log_format(ab, " key=");
 				audit_log_untrustedstring(ab, r->filterkey);
 			} else
 				audit_log_format(ab, " key=(null)");
-			audit_log_format(ab, " list=%d", r->listnr);
+			audit_log_format(ab, " list=%d res=1", r->listnr);
 			audit_log_end(ab);
 
 			list_del(&r->rlist);
@@ -1410,7 +1411,7 @@
 			audit_log_format(ab, " subj=%s", ctx);
 		kfree(ctx);
 	}
-	audit_log_format(ab, " %s rule key=", action);
+	audit_log_format(ab, " op=%s rule key=", action);
 	if (rule->filterkey)
 		audit_log_untrustedstring(ab, rule->filterkey);
 	else
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 2988975..3599558 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -170,6 +170,11 @@
 	char			a[0];
 };
 
+struct audit_aux_data_fd_pair {
+	struct	audit_aux_data d;
+	int	fd[2];
+};
+
 struct audit_aux_data_path {
 	struct audit_aux_data	d;
 	struct dentry		*dentry;
@@ -961,6 +966,11 @@
 			audit_log_d_path(ab, "path=", axi->dentry, axi->mnt);
 			break; }
 
+		case AUDIT_FD_PAIR: {
+			struct audit_aux_data_fd_pair *axs = (void *)aux;
+			audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]);
+			break; }
+
 		}
 		audit_log_end(ab);
 	}
@@ -1815,6 +1825,36 @@
 }
 
 /**
+ * __audit_fd_pair - record audit data for pipe and socketpair
+ * @fd1: the first file descriptor
+ * @fd2: the second file descriptor
+ *
+ * Returns 0 for success or NULL context or < 0 on error.
+ */
+int __audit_fd_pair(int fd1, int fd2)
+{
+	struct audit_context *context = current->audit_context;
+	struct audit_aux_data_fd_pair *ax;
+
+	if (likely(!context)) {
+		return 0;
+	}
+
+	ax = kmalloc(sizeof(*ax), GFP_KERNEL);
+	if (!ax) {
+		return -ENOMEM;
+	}
+
+	ax->fd[0] = fd1;
+	ax->fd[1] = fd2;
+
+	ax->d.type = AUDIT_FD_PAIR;
+	ax->d.next = context->aux;
+	context->aux = (void *)ax;
+	return 0;
+}
+
+/**
  * audit_sockaddr - record audit data for sys_bind, sys_connect, sys_sendto
  * @len: data length in user space
  * @a: data address in kernel space
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 7962761..9f923f8 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -36,6 +36,8 @@
 #include <linux/resource.h>
 #include <asm/uaccess.h>
 
+extern int delete_module(const char *name, unsigned int flags);
+
 extern int max_threads;
 
 static struct workqueue_struct *khelper_wq;
@@ -46,6 +48,7 @@
 	modprobe_path is set via /proc/sys.
 */
 char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
+struct module_kobject kmod_mk;
 
 /**
  * request_module - try to load a kernel module
@@ -75,6 +78,11 @@
 	static atomic_t kmod_concurrent = ATOMIC_INIT(0);
 #define MAX_KMOD_CONCURRENT 50	/* Completely arbitrary value - KAO */
 	static int kmod_loop_msg;
+	char modalias[16 + MODULE_NAME_LEN] = "MODALIAS=";
+	char *uevent_envp[2] = {
+		modalias,
+		NULL
+	};
 
 	va_start(args, fmt);
 	ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
@@ -82,6 +90,12 @@
 	if (ret >= MODULE_NAME_LEN)
 		return -ENAMETOOLONG;
 
+	strcpy(&modalias[strlen("MODALIAS=")], module_name);
+	kobject_uevent_env(&kmod_mk.kobj, KOBJ_CHANGE, uevent_envp);
+
+	if (modprobe_path[0] == '\0')
+		goto out;
+
 	/* If modprobe needs a service that is in a module, we get a recursive
 	 * loop.  Limit the number of running kmod threads to max_threads/2 or
 	 * MAX_KMOD_CONCURRENT, whichever is the smaller.  A cleaner method
@@ -108,9 +122,115 @@
 
 	ret = call_usermodehelper(modprobe_path, argv, envp, 1);
 	atomic_dec(&kmod_concurrent);
+out:
 	return ret;
 }
 EXPORT_SYMBOL(request_module);
+
+static ssize_t store_mod_request(struct module_attribute *mattr,
+				 struct module *mod,
+			      const char *buffer, size_t count)
+{
+	char name[MODULE_NAME_LEN];
+	int ret;
+
+	if (count < 1 || count+1 > MODULE_NAME_LEN)
+		return -EINVAL;
+	memcpy(name, buffer, count);
+	name[count] = '\0';
+	if (name[count-1] == '\n')
+		name[count-1] = '\0';
+
+	ret = request_module(name);
+	if (ret < 0)
+		return ret;
+	return count;
+}
+
+static struct module_attribute mod_request = {
+	.attr = { .name = "mod_request", .mode = S_IWUSR, .owner = THIS_MODULE },
+	.store = store_mod_request,
+};
+
+#ifdef CONFIG_MODULE_UNLOAD
+static ssize_t store_mod_unload(struct module_attribute *mattr,
+			    struct module *mod,
+			    const char *buffer, size_t count)
+{
+	char name[MODULE_NAME_LEN];
+	int ret;
+
+	if (count < 1 || count+1 > MODULE_NAME_LEN)
+		return -EINVAL;
+	memcpy(name, buffer, count);
+	name[count] = '\0';
+	if (name[count-1] == '\n')
+		name[count-1] = '\0';
+
+	ret = delete_module(name, O_NONBLOCK);
+	if (ret < 0)
+		return ret;
+	return count;
+}
+
+static struct module_attribute mod_unload = {
+	.attr = { .name = "mod_unload", .mode = S_IWUSR, .owner = THIS_MODULE },
+	.store = store_mod_unload,
+};
+#endif
+
+static ssize_t show_mod_request_helper(struct module_attribute *mattr,
+				       struct module *mod,
+				       char *buffer)
+{
+	return sprintf(buffer, "%s\n", modprobe_path);
+}
+
+static ssize_t store_mod_request_helper(struct module_attribute *mattr,
+					struct module *mod,
+					const char *buffer, size_t count)
+{
+	if (count < 1 || count+1 > KMOD_PATH_LEN)
+		return -EINVAL;
+	memcpy(modprobe_path, buffer, count);
+	modprobe_path[count] = '\0';
+	if (modprobe_path[count-1] == '\n')
+		modprobe_path[count-1] = '\0';
+	return count;
+}
+
+static struct module_attribute mod_request_helper = {
+	.attr = {
+		.name = "mod_request_helper",
+		.mode = S_IWUSR | S_IRUGO,
+		.owner = THIS_MODULE
+	},
+	.show = show_mod_request_helper,
+	.store = store_mod_request_helper,
+};
+
+void __init kmod_sysfs_init(void)
+{
+	int ret;
+
+	kmod_mk.mod = THIS_MODULE;
+	kobj_set_kset_s(&kmod_mk, module_subsys);
+	kobject_set_name(&kmod_mk.kobj, "kmod");
+	kobject_init(&kmod_mk.kobj);
+	ret = kobject_add(&kmod_mk.kobj);
+	if (ret < 0)
+		goto out;
+
+	ret = sysfs_create_file(&kmod_mk.kobj, &mod_request_helper.attr);
+	ret = sysfs_create_file(&kmod_mk.kobj, &mod_request.attr);
+#ifdef CONFIG_MODULE_UNLOAD
+	ret = sysfs_create_file(&kmod_mk.kobj, &mod_unload.attr);
+#endif
+
+	kobject_uevent(&kmod_mk.kobj, KOBJ_ADD);
+out:
+	return;
+}
 #endif /* CONFIG_KMOD */
 
 struct subprocess_info {
diff --git a/kernel/module.c b/kernel/module.c
index 8a94e05..8c25b1a 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -653,20 +653,11 @@
 	mutex_lock(&module_mutex);
 }
 
-asmlinkage long
-sys_delete_module(const char __user *name_user, unsigned int flags)
+int delete_module(const char *name, unsigned int flags)
 {
 	struct module *mod;
-	char name[MODULE_NAME_LEN];
 	int ret, forced = 0;
 
-	if (!capable(CAP_SYS_MODULE))
-		return -EPERM;
-
-	if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
-		return -EFAULT;
-	name[MODULE_NAME_LEN-1] = '\0';
-
 	if (mutex_lock_interruptible(&module_mutex) != 0)
 		return -EINTR;
 
@@ -727,6 +718,21 @@
 	return ret;
 }
 
+asmlinkage long
+sys_delete_module(const char __user *name_user, unsigned int flags)
+{
+	char name[MODULE_NAME_LEN];
+
+	if (!capable(CAP_SYS_MODULE))
+		return -EPERM;
+
+	if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
+		return -EFAULT;
+	name[MODULE_NAME_LEN-1] = '\0';
+
+	return delete_module(name, flags);
+}
+
 static void print_unload_info(struct seq_file *m, struct module *mod)
 {
 	struct module_use *use;
@@ -1068,7 +1074,8 @@
 }
 #endif /* CONFIG_KALLSYMS */
 
-static int module_add_modinfo_attrs(struct module *mod)
+#ifdef CONFIG_SYSFS
+int module_add_modinfo_attrs(struct module *mod)
 {
 	struct module_attribute *attr;
 	struct module_attribute *temp_attr;
@@ -1094,7 +1101,7 @@
 	return error;
 }
 
-static void module_remove_modinfo_attrs(struct module *mod)
+void module_remove_modinfo_attrs(struct module *mod)
 {
 	struct module_attribute *attr;
 	int i;
@@ -1109,8 +1116,10 @@
 	}
 	kfree(mod->modinfo_attrs);
 }
+#endif
 
-static int mod_sysfs_init(struct module *mod)
+#ifdef CONFIG_SYSFS
+int mod_sysfs_init(struct module *mod)
 {
 	int err;
 
@@ -1133,7 +1142,7 @@
 	return err;
 }
 
-static int mod_sysfs_setup(struct module *mod,
+int mod_sysfs_setup(struct module *mod,
 			   struct kernel_param *kparam,
 			   unsigned int num_params)
 {
@@ -1169,16 +1178,14 @@
 out:
 	return err;
 }
+#endif
 
 static void mod_kobject_remove(struct module *mod)
 {
 	module_remove_modinfo_attrs(mod);
 	module_param_sysfs_remove(mod);
-	if (mod->mkobj.drivers_dir)
-		kobject_unregister(mod->mkobj.drivers_dir);
-	if (mod->holders_dir)
-		kobject_unregister(mod->holders_dir);
-
+	kobject_unregister(mod->mkobj.drivers_dir);
+	kobject_unregister(mod->holders_dir);
 	kobject_unregister(&mod->mkobj.kobj);
 }
 
@@ -2345,6 +2352,7 @@
 	printk("\n");
 }
 
+#ifdef CONFIG_SYSFS
 static char *make_driver_name(struct device_driver *drv)
 {
 	char *driver_name;
@@ -2419,6 +2427,7 @@
 	}
 }
 EXPORT_SYMBOL(module_remove_driver);
+#endif
 
 #ifdef CONFIG_MODVERSIONS
 /* Generate the signature for struct module here, too, for modversions. */
diff --git a/kernel/params.c b/kernel/params.c
index 553cf7d..7a75157 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -30,8 +30,6 @@
 #define DEBUGP(fmt, a...)
 #endif
 
-static struct kobj_type module_ktype;
-
 static inline char dash2underscore(char c)
 {
 	if (c == '-')
@@ -391,6 +389,7 @@
 	struct param_attribute attrs[0];
 };
 
+#ifdef CONFIG_SYSFS
 #define to_param_attr(n) container_of(n, struct param_attribute, mattr);
 
 static ssize_t param_attr_show(struct module_attribute *mattr,
@@ -426,6 +425,7 @@
 		return len;
 	return err;
 }
+#endif
 
 #ifdef CONFIG_MODULES
 #define __modinit
@@ -433,6 +433,7 @@
 #define __modinit __init
 #endif
 
+#ifdef CONFIG_SYSFS
 /*
  * param_sysfs_setup - setup sysfs support for one module or KBUILD_MODNAME
  * @mk: struct module_kobject (contains parent kobject)
@@ -500,9 +501,7 @@
 	return mp;
 }
 
-
 #ifdef CONFIG_MODULES
-
 /*
  * module_param_sysfs_setup - setup sysfs support for one module
  * @mod: module
@@ -625,7 +624,6 @@
 
 
 /* module-related sysfs stuff */
-#ifdef CONFIG_SYSFS
 
 #define to_module_attr(n) container_of(n, struct module_attribute, attr);
 #define to_module_kobject(n) container_of(n, struct module_kobject, kobj);
@@ -673,6 +671,8 @@
 	.store = module_attr_store,
 };
 
+static struct kobj_type module_ktype;
+
 static int uevent_filter(struct kset *kset, struct kobject *kobj)
 {
 	struct kobj_type *ktype = get_ktype(kobj);
@@ -686,19 +686,12 @@
 	.filter = uevent_filter,
 };
 
-#else
-static struct sysfs_ops module_sysfs_ops = {
-	.show = NULL,
-	.store = NULL,
-};
-#endif
+decl_subsys(module, &module_ktype, &module_uevent_ops);
 
 static struct kobj_type module_ktype = {
 	.sysfs_ops =	&module_sysfs_ops,
 };
 
-decl_subsys(module, &module_ktype, &module_uevent_ops);
-
 /*
  * param_sysfs_init - wrapper for built-in params support
  */
@@ -714,11 +707,21 @@
 	}
 
 	param_sysfs_builtin();
+	kmod_sysfs_init();
 
 	return 0;
 }
 subsys_initcall(param_sysfs_init);
 
+#else
+#if 0
+static struct sysfs_ops module_sysfs_ops = {
+	.show = NULL,
+	.store = NULL,
+};
+#endif
+#endif
+
 EXPORT_SYMBOL(param_set_byte);
 EXPORT_SYMBOL(param_get_byte);
 EXPORT_SYMBOL(param_set_short);
diff --git a/kernel/printk.c b/kernel/printk.c
index 0c15187..4b47e59 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -54,7 +54,7 @@
 };
 
 /*
- * Low lever drivers may need that to know if they can schedule in
+ * Low level drivers may need that to know if they can schedule in
  * their unblank() callback or not. So let's export it.
  */
 int oops_in_progress;
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 95e41f7f..512a4a9 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -165,7 +165,9 @@
 		goto end;
 
 	cpu = smp_processor_id();
-	BUG_ON(local_softirq_pending());
+	if (unlikely(local_softirq_pending()))
+		printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n",
+		       local_softirq_pending());
 
 	now = ktime_get();
 	/*
@@ -191,19 +193,19 @@
 	next_jiffies = get_next_timer_interrupt(last_jiffies);
 	delta_jiffies = next_jiffies - last_jiffies;
 
+	if (rcu_needs_cpu(cpu))
+		delta_jiffies = 1;
 	/*
 	 * Do not stop the tick, if we are only one off
 	 * or if the cpu is required for rcu
 	 */
-	if (!ts->tick_stopped && (delta_jiffies == 1 || rcu_needs_cpu(cpu)))
+	if (!ts->tick_stopped && delta_jiffies == 1)
 		goto out;
 
 	/* Schedule the tick, if we are at least one jiffie off */
 	if ((long)delta_jiffies >= 1) {
 
-		if (rcu_needs_cpu(cpu))
-			delta_jiffies = 1;
-		else
+		if (delta_jiffies > 1)
 			cpu_set(cpu, nohz_cpu_mask);
 		/*
 		 * nohz_stop_sched_tick can be called several times before
diff --git a/lib/kobject.c b/lib/kobject.c
index 2782f49..f4f6176 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -171,7 +171,7 @@
 		return -ENOENT;
 	if (!kobj->k_name)
 		kobj->k_name = kobj->name;
-	if (!kobj->k_name) {
+	if (!*kobj->k_name) {
 		pr_debug("kobject attempted to be registered with no name!\n");
 		WARN_ON(1);
 		return -EINVAL;
@@ -326,6 +326,7 @@
 /**
  *	kobject_rename - change the name of an object
  *	@kobj:	object in question.
+ *	@new_parent: object's new parent
  *	@new_name: object's new name
  */
 
diff --git a/lib/textsearch.c b/lib/textsearch.c
index 9e2a002..88c98a2 100644
--- a/lib/textsearch.c
+++ b/lib/textsearch.c
@@ -40,7 +40,7 @@
  *       configuration according to the specified parameters.
  *   (3) User starts the search(es) by calling _find() or _next() to
  *       fetch subsequent occurrences. A state variable is provided
- *       to the algorihtm to store persistent variables.
+ *       to the algorithm to store persistent variables.
  *   (4) Core eventually resets the search offset and forwards the find()
  *       request to the algorithm.
  *   (5) Algorithm calls get_next_block() provided by the user continously
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 503e705..91f3a5c 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -9,7 +9,7 @@
 	  intend to participate in the MBONE, a high bandwidth network on top
 	  of the Internet which carries audio and video broadcasts. More
 	  information about the MBONE is on the WWW at
-	  <http://www-itg.lbl.gov/mbone/>. Information about the multicast
+	  <http://www.savetz.com/mbone/>. Information about the multicast
 	  capabilities of the various network cards is contained in
 	  <file:Documentation/networking/multicast.txt>. For most people, it's
 	  safe to say N.
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index c1b34f1..5c8caf4 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -29,7 +29,7 @@
 }
 
 /*
- * Attach new congestion control algorthim to the list
+ * Attach new congestion control algorithm to the list
  * of available options.
  */
 int tcp_register_congestion_control(struct tcp_congestion_ops *ca)
diff --git a/net/socket.c b/net/socket.c
index 0778c54..9566e57 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1194,6 +1194,7 @@
 {
 	struct socket *sock1, *sock2;
 	int fd1, fd2, err;
+	struct file *newfile1, *newfile2;
 
 	/*
 	 * Obtain the first socket and check if the underlying protocol
@@ -1212,18 +1213,37 @@
 	if (err < 0)
 		goto out_release_both;
 
-	fd1 = fd2 = -1;
-
-	err = sock_map_fd(sock1);
-	if (err < 0)
+	fd1 = sock_alloc_fd(&newfile1);
+	if (unlikely(fd1 < 0))
 		goto out_release_both;
-	fd1 = err;
 
-	err = sock_map_fd(sock2);
-	if (err < 0)
-		goto out_close_1;
-	fd2 = err;
+	fd2 = sock_alloc_fd(&newfile2);
+	if (unlikely(fd2 < 0)) {
+		put_filp(newfile1);
+		put_unused_fd(fd1);
+		goto out_release_both;
+	}
 
+	err = sock_attach_fd(sock1, newfile1);
+	if (unlikely(err < 0)) {
+		goto out_fd2;
+	}
+
+	err = sock_attach_fd(sock2, newfile2);
+	if (unlikely(err < 0)) {
+		fput(newfile1);
+		goto out_fd1;
+	}
+
+	err = audit_fd_pair(fd1, fd2);
+	if (err < 0) {
+		fput(newfile1);
+		fput(newfile2);
+		goto out_fd;
+	}
+
+	fd_install(fd1, newfile1);
+	fd_install(fd2, newfile2);
 	/* fd1 and fd2 may be already another descriptors.
 	 * Not kernel problem.
 	 */
@@ -1238,17 +1258,23 @@
 	sys_close(fd1);
 	return err;
 
-out_close_1:
-	sock_release(sock2);
-	sys_close(fd1);
-	return err;
-
 out_release_both:
 	sock_release(sock2);
 out_release_1:
 	sock_release(sock1);
 out:
 	return err;
+
+out_fd2:
+	put_filp(newfile1);
+	sock_release(sock1);
+out_fd1:
+	put_filp(newfile2);
+	sock_release(sock2);
+out_fd:
+	put_unused_fd(fd1);
+	put_unused_fd(fd2);
+	goto out;
 }
 
 /*
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 53675cf..5190d7a 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -65,10 +65,12 @@
  *  SI1TxEn, SI2TxEn and SI12TxEn bits are set in the AACI_MAINCR
  *  register.
  */
-static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
+static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
+			    unsigned short val)
 {
 	struct aaci *aaci = ac97->private_data;
 	u32 v;
+	int timeout = 5000;
 
 	if (ac97->num >= 4)
 		return;
@@ -89,7 +91,11 @@
 	 */
 	do {
 		v = readl(aaci->base + AACI_SLFR);
-	} while (v & (SLFR_1TXB|SLFR_2TXB));
+	} while ((v & (SLFR_1TXB|SLFR_2TXB)) && timeout--);
+
+	if (!timeout)
+		dev_err(&aaci->dev->dev,
+			"timeout waiting for write to complete\n");
 
 	mutex_unlock(&aaci->ac97_sem);
 }
@@ -101,6 +107,8 @@
 {
 	struct aaci *aaci = ac97->private_data;
 	u32 v;
+	int timeout = 5000;
+	int retries = 10;
 
 	if (ac97->num >= 4)
 		return ~0;
@@ -119,7 +127,13 @@
 	 */
 	do {
 		v = readl(aaci->base + AACI_SLFR);
-	} while (v & SLFR_1TXB);
+	} while ((v & SLFR_1TXB) && timeout--);
+
+	if (!timeout) {
+		dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n");
+		v = ~0;
+		goto out;
+	}
 
 	/*
 	 * Give the AC'97 codec more than enough time
@@ -130,21 +144,35 @@
 	/*
 	 * Wait for slot 2 to indicate data.
 	 */
+	timeout = 5000;
 	do {
 		cond_resched();
 		v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV);
-	} while (v != (SLFR_1RXV|SLFR_2RXV));
+	} while ((v != (SLFR_1RXV|SLFR_2RXV)) && timeout--);
 
-	v = readl(aaci->base + AACI_SL1RX) >> 12;
-	if (v == reg) {
-		v = readl(aaci->base + AACI_SL2RX) >> 4;
-	} else {
-		dev_err(&aaci->dev->dev,
-			"wrong ac97 register read back (%x != %x)\n",
-			v, reg);
+	if (!timeout) {
+		dev_err(&aaci->dev->dev, "timeout on RX valid\n");
 		v = ~0;
+		goto out;
 	}
 
+	do {
+		v = readl(aaci->base + AACI_SL1RX) >> 12;
+		if (v == reg) {
+			v = readl(aaci->base + AACI_SL2RX) >> 4;
+			break;
+		} else if (--retries) {
+			dev_warn(&aaci->dev->dev,
+				 "ac97 read back fail.  retry\n");
+			continue;
+		} else {
+			dev_warn(&aaci->dev->dev,
+				"wrong ac97 register read back (%x != %x)\n",
+				v, reg);
+			v = ~0;
+		}
+	} while (retries);
+ out:
 	mutex_unlock(&aaci->ac97_sem);
 	return v;
 }
@@ -164,10 +192,70 @@
 /*
  * Interrupt support.
  */
-static void aaci_fifo_irq(struct aaci *aaci, u32 mask)
+static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
 {
+	if (mask & ISR_ORINTR) {
+		dev_warn(&aaci->dev->dev, "RX overrun on chan %d\n", channel);
+		writel(ICLR_RXOEC1 << channel, aaci->base + AACI_INTCLR);
+	}
+
+	if (mask & ISR_RXTOINTR) {
+		dev_warn(&aaci->dev->dev, "RX timeout on chan %d\n", channel);
+		writel(ICLR_RXTOFEC1 << channel, aaci->base + AACI_INTCLR);
+	}
+
+	if (mask & ISR_RXINTR) {
+		struct aaci_runtime *aacirun = &aaci->capture;
+		void *ptr;
+
+		if (!aacirun->substream || !aacirun->start) {
+			dev_warn(&aaci->dev->dev, "RX interrupt???");
+			writel(0, aacirun->base + AACI_IE);
+			return;
+		}
+		ptr = aacirun->ptr;
+
+		do {
+			unsigned int len = aacirun->fifosz;
+			u32 val;
+
+			if (aacirun->bytes <= 0) {
+				aacirun->bytes += aacirun->period;
+				aacirun->ptr = ptr;
+				spin_unlock(&aaci->lock);
+				snd_pcm_period_elapsed(aacirun->substream);
+				spin_lock(&aaci->lock);
+			}
+			if (!(aacirun->cr & CR_EN))
+				break;
+
+			val = readl(aacirun->base + AACI_SR);
+			if (!(val & SR_RXHF))
+				break;
+			if (!(val & SR_RXFF))
+				len >>= 1;
+
+			aacirun->bytes -= len;
+
+			/* reading 16 bytes at a time */
+			for( ; len > 0; len -= 16) {
+				asm(
+					"ldmia	%1, {r0, r1, r2, r3}\n\t"
+					"stmia	%0!, {r0, r1, r2, r3}"
+					: "+r" (ptr)
+					: "r" (aacirun->fifo)
+					: "r0", "r1", "r2", "r3", "cc");
+
+				if (ptr >= aacirun->end)
+					ptr = aacirun->start;
+			}
+		} while(1);
+		aacirun->ptr = ptr;
+	}
+
 	if (mask & ISR_URINTR) {
-		writel(ICLR_TXUEC1, aaci->base + AACI_INTCLR);
+		dev_dbg(&aaci->dev->dev, "TX underrun on chan %d\n", channel);
+		writel(ICLR_TXUEC1 << channel, aaci->base + AACI_INTCLR);
 	}
 
 	if (mask & ISR_TXINTR) {
@@ -192,7 +280,7 @@
 				snd_pcm_period_elapsed(aacirun->substream);
 				spin_lock(&aaci->lock);
 			}
-			if (!(aacirun->cr & TXCR_TXEN))
+			if (!(aacirun->cr & CR_EN))
 				break;
 
 			val = readl(aacirun->base + AACI_SR);
@@ -233,7 +321,7 @@
 		u32 m = mask;
 		for (i = 0; i < 4; i++, m >>= 7) {
 			if (m & 0x7f) {
-				aaci_fifo_irq(aaci, m);
+				aaci_fifo_irq(aaci, i, m);
 			}
 		}
 	}
@@ -330,8 +418,9 @@
 	.periods_max		= PAGE_SIZE / 16,
 };
 
-static int aaci_pcm_open(struct aaci *aaci, struct snd_pcm_substream *substream,
-			 struct aaci_runtime *aacirun)
+static int __aaci_pcm_open(struct aaci *aaci,
+			   struct snd_pcm_substream *substream,
+			   struct aaci_runtime *aacirun)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	int ret;
@@ -380,7 +469,7 @@
 	struct aaci *aaci = substream->private_data;
 	struct aaci_runtime *aacirun = substream->runtime->private_data;
 
-	WARN_ON(aacirun->cr & TXCR_TXEN);
+	WARN_ON(aacirun->cr & CR_EN);
 
 	aacirun->substream = NULL;
 	free_irq(aaci->dev->irq[0], aaci);
@@ -395,7 +484,7 @@
 	/*
 	 * This must not be called with the device enabled.
 	 */
-	WARN_ON(aacirun->cr & TXCR_TXEN);
+	WARN_ON(aacirun->cr & CR_EN);
 
 	if (aacirun->pcm_open)
 		snd_ac97_pcm_close(aacirun->pcm);
@@ -422,9 +511,15 @@
 	if (err < 0)
 		goto out;
 
-	err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
-				params_channels(params),
-				aacirun->pcm->r[0].slots);
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
+					params_channels(params),
+					aacirun->pcm->r[0].slots);
+	else
+		err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
+					params_channels(params),
+					aacirun->pcm->r[1].slots);
+
 	if (err)
 		goto out;
 
@@ -467,9 +562,9 @@
  * Playback specific ALSA stuff
  */
 static const u32 channels_to_txmask[] = {
-	[2] = TXCR_TX3 | TXCR_TX4,
-	[4] = TXCR_TX3 | TXCR_TX4 | TXCR_TX7 | TXCR_TX8,
-	[6] = TXCR_TX3 | TXCR_TX4 | TXCR_TX7 | TXCR_TX8 | TXCR_TX6 | TXCR_TX9,
+	[2] = CR_SL3 | CR_SL4,
+	[4] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8,
+	[6] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8 | CR_SL6 | CR_SL9,
 };
 
 /*
@@ -504,7 +599,7 @@
 				 chan_mask);
 }
 
-static int aaci_pcm_playback_open(struct snd_pcm_substream *substream)
+static int aaci_pcm_open(struct snd_pcm_substream *substream)
 {
 	struct aaci *aaci = substream->private_data;
 	int ret;
@@ -519,7 +614,12 @@
 	if (ret)
 		return ret;
 
-	return aaci_pcm_open(aaci, substream, &aaci->playback);
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		ret = __aaci_pcm_open(aaci, substream, &aaci->playback);
+	} else {
+		ret = __aaci_pcm_open(aaci, substream, &aaci->capture);
+	}
+	return ret;
 }
 
 static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream,
@@ -540,11 +640,11 @@
 	 * FIXME: double rate slots?
 	 */
 	if (ret >= 0) {
-		aacirun->cr = TXCR_FEN | TXCR_COMPACT | TXCR_TSZ16;
+		aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
 		aacirun->cr |= channels_to_txmask[channels];
 
 		aacirun->fifosz	= aaci->fifosize * 4;
-		if (aacirun->cr & TXCR_COMPACT)
+		if (aacirun->cr & CR_COMPACT)
 			aacirun->fifosz >>= 1;
 	}
 	return ret;
@@ -557,7 +657,7 @@
 	ie = readl(aacirun->base + AACI_IE);
 	ie &= ~(IE_URIE|IE_TXIE);
 	writel(ie, aacirun->base + AACI_IE);
-	aacirun->cr &= ~TXCR_TXEN;
+	aacirun->cr &= ~CR_EN;
 	aaci_chan_wait_ready(aacirun);
 	writel(aacirun->cr, aacirun->base + AACI_TXCR);
 }
@@ -567,7 +667,7 @@
 	u32 ie;
 
 	aaci_chan_wait_ready(aacirun);
-	aacirun->cr |= TXCR_TXEN;
+	aacirun->cr |= CR_EN;
 
 	ie = readl(aacirun->base + AACI_IE);
 	ie |= IE_URIE | IE_TXIE;
@@ -615,7 +715,7 @@
 }
 
 static struct snd_pcm_ops aaci_playback_ops = {
-	.open		= aaci_pcm_playback_open,
+	.open		= aaci_pcm_open,
 	.close		= aaci_pcm_close,
 	.ioctl		= snd_pcm_lib_ioctl,
 	.hw_params	= aaci_pcm_playback_hw_params,
@@ -626,7 +726,133 @@
 	.mmap		= aaci_pcm_mmap,
 };
 
+static int aaci_pcm_capture_hw_params(snd_pcm_substream_t *substream,
+				      snd_pcm_hw_params_t *params)
+{
+	struct aaci *aaci = substream->private_data;
+	struct aaci_runtime *aacirun = substream->runtime->private_data;
+	int ret;
 
+	ret = aaci_pcm_hw_params(substream, aacirun, params);
+
+	if (ret >= 0) {
+		aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
+
+		/* Line in record: slot 3 and 4 */
+		aacirun->cr |= CR_SL3 | CR_SL4;
+
+		aacirun->fifosz = aaci->fifosize * 4;
+
+		if (aacirun->cr & CR_COMPACT)
+			aacirun->fifosz >>= 1;
+	}
+	return ret;
+}
+
+static void aaci_pcm_capture_stop(struct aaci_runtime *aacirun)
+{
+	u32 ie;
+
+	aaci_chan_wait_ready(aacirun);
+
+	ie = readl(aacirun->base + AACI_IE);
+	ie &= ~(IE_ORIE | IE_RXIE);
+	writel(ie, aacirun->base+AACI_IE);
+
+	aacirun->cr &= ~CR_EN;
+
+	writel(aacirun->cr, aacirun->base + AACI_RXCR);
+}
+
+static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
+{
+	u32 ie;
+
+	aaci_chan_wait_ready(aacirun);
+
+#ifdef DEBUG
+	/* RX Timeout value: bits 28:17 in RXCR */
+	aacirun->cr |= 0xf << 17;
+#endif
+
+	aacirun->cr |= CR_EN;
+	writel(aacirun->cr, aacirun->base + AACI_RXCR);
+
+	ie = readl(aacirun->base + AACI_IE);
+	ie |= IE_ORIE |IE_RXIE; // overrun and rx interrupt -- half full
+	writel(ie, aacirun->base + AACI_IE);
+}
+
+static int aaci_pcm_capture_trigger(snd_pcm_substream_t *substream, int cmd){
+
+	struct aaci *aaci = substream->private_data;
+	struct aaci_runtime *aacirun = substream->runtime->private_data;
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&aaci->lock, flags);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		aaci_pcm_capture_start(aacirun);
+		break;
+
+	case SNDRV_PCM_TRIGGER_RESUME:
+		aaci_pcm_capture_start(aacirun);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+		aaci_pcm_capture_stop(aacirun);
+		break;
+
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+		aaci_pcm_capture_stop(aacirun);
+		break;
+
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		break;
+
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		break;
+
+	default:
+		ret = -EINVAL;
+	}
+
+	spin_unlock_irqrestore(&aaci->lock, flags);
+
+	return ret;
+}
+
+static int aaci_pcm_capture_prepare(snd_pcm_substream_t *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct aaci *aaci = substream->private_data;
+
+	aaci_pcm_prepare(substream);
+
+	/* allow changing of sample rate */
+	aaci_ac97_write(aaci->ac97, AC97_EXTENDED_STATUS, 0x0001); /* VRA */
+	aaci_ac97_write(aaci->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
+	aaci_ac97_write(aaci->ac97, AC97_PCM_MIC_ADC_RATE, runtime->rate);
+
+	/* Record select: Mic: 0, Aux: 3, Line: 4 */
+	aaci_ac97_write(aaci->ac97, AC97_REC_SEL, 0x0404);
+
+	return 0;
+}
+
+static snd_pcm_ops_t aaci_capture_ops = {
+	.open		= aaci_pcm_open,
+	.close		= aaci_pcm_close,
+	.ioctl		= snd_pcm_lib_ioctl,
+	.hw_params	= aaci_pcm_capture_hw_params,
+	.hw_free	= aaci_pcm_hw_free,
+	.prepare	= aaci_pcm_capture_prepare,
+	.trigger	= aaci_pcm_capture_trigger,
+	.pointer	= aaci_pcm_pointer,
+	.mmap		= aaci_pcm_mmap,
+};
 
 /*
  * Power Management.
@@ -666,7 +892,7 @@
 
 
 static struct ac97_pcm ac97_defs[] __devinitdata = {
-	[0] = {		/* Front PCM */
+	[0] = {	/* Front PCM */
 		.exclusive = 1,
 		.r = {
 			[0] = {
@@ -740,6 +966,7 @@
 	ret = snd_ac97_mixer(ac97_bus, &ac97_template, &ac97);
 	if (ret)
 		goto out;
+	aaci->ac97 = ac97;
 
 	/*
 	 * Disable AC97 PC Beep input on audio codecs.
@@ -752,6 +979,7 @@
 		goto out;
 
 	aaci->playback.pcm = &ac97_bus->pcms[0];
+	aaci->capture.pcm  = &ac97_bus->pcms[1];
 
  out:
 	return ret;
@@ -801,7 +1029,7 @@
 	struct snd_pcm *pcm;
 	int ret;
 
-	ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 0, &pcm);
+	ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 1, &pcm);
 	if (ret == 0) {
 		aaci->pcm = pcm;
 		pcm->private_data = aaci;
@@ -810,6 +1038,7 @@
 		strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
 
 		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops);
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops);
 	}
 
 	return ret;
@@ -817,15 +1046,15 @@
 
 static unsigned int __devinit aaci_size_fifo(struct aaci *aaci)
 {
-	void __iomem *base = aaci->base + AACI_CSCH1;
+	struct aaci_runtime *aacirun = &aaci->playback;
 	int i;
 
-	writel(TXCR_FEN | TXCR_TSZ16 | TXCR_TXEN, base + AACI_TXCR);
+	writel(CR_FEN | CR_SZ16 | CR_EN, aacirun->base + AACI_TXCR);
 
-	for (i = 0; !(readl(base + AACI_SR) & SR_TXFF) && i < 4096; i++)
-		writel(0, aaci->base + AACI_DR1);
+	for (i = 0; !(readl(aacirun->base + AACI_SR) & SR_TXFF) && i < 4096; i++)
+		writel(0, aacirun->fifo);
 
-	writel(0, base + AACI_TXCR);
+	writel(0, aacirun->base + AACI_TXCR);
 
 	/*
 	 * Re-initialise the AACI after the FIFO depth test, to
@@ -872,6 +1101,12 @@
 	aaci->playback.base = aaci->base + AACI_CSCH1;
 	aaci->playback.fifo = aaci->base + AACI_DR1;
 
+	/*
+	 * Capture uses AACI channel 0
+	 */
+	aaci->capture.base = aaci->base + AACI_CSCH1;
+	aaci->capture.fifo = aaci->base + AACI_DR1;
+
 	for (i = 0; i < 4; i++) {
 		void __iomem *base = aaci->base + i * 0x14;
 
@@ -907,7 +1142,7 @@
 	ret = snd_card_register(aaci->card);
 	if (ret == 0) {
 		dev_info(&dev->dev, "%s, fifo %d\n", aaci->card->longname,
-			aaci->fifosize);
+			 aaci->fifosize);
 		amba_set_drvdata(dev, aaci->card);
 		return ret;
 	}
diff --git a/sound/arm/aaci.h b/sound/arm/aaci.h
index 9175ff9..924f69c 100644
--- a/sound/arm/aaci.h
+++ b/sound/arm/aaci.h
@@ -49,27 +49,27 @@
 #define AACI_DR4	0x0f0	/* data read/written fifo 4 */
 
 /*
- * transmit fifo control register. P48
+ * TX/RX fifo control register (CR). P48
  */
-#define TXCR_FEN	(1 << 16)	/* fifo enable */
-#define TXCR_COMPACT	(1 << 15)	/* compact mode */
-#define TXCR_TSZ16	(0 << 13)	/* 16 bits */
-#define TXCR_TSZ18	(1 << 13)	/* 18 bits */
-#define TXCR_TSZ20	(2 << 13)	/* 20 bits */
-#define TXCR_TSZ12	(3 << 13)	/* 12 bits */
-#define TXCR_TX12	(1 << 12)	/* transmits slot 12 */
-#define TXCR_TX11	(1 << 11)	/* transmits slot 12 */
-#define TXCR_TX10	(1 << 10)	/* transmits slot 12 */
-#define TXCR_TX9	(1 << 9)	/* transmits slot 12 */
-#define TXCR_TX8	(1 << 8)	/* transmits slot 12 */
-#define TXCR_TX7	(1 << 7)	/* transmits slot 12 */
-#define TXCR_TX6	(1 << 6)	/* transmits slot 12 */
-#define TXCR_TX5	(1 << 5)	/* transmits slot 12 */
-#define TXCR_TX4	(1 << 4)	/* transmits slot 12 */
-#define TXCR_TX3	(1 << 3)	/* transmits slot 12 */
-#define TXCR_TX2	(1 << 2)	/* transmits slot 12 */
-#define TXCR_TX1	(1 << 1)	/* transmits slot 12 */
-#define TXCR_TXEN	(1 << 0)	/* transmit enable */
+#define CR_FEN		(1 << 16)	/* fifo enable */
+#define CR_COMPACT	(1 << 15)	/* compact mode */
+#define CR_SZ16		(0 << 13)	/* 16 bits */
+#define CR_SZ18		(1 << 13)	/* 18 bits */
+#define CR_SZ20		(2 << 13)	/* 20 bits */
+#define CR_SZ12		(3 << 13)	/* 12 bits */
+#define CR_SL12		(1 << 12)
+#define CR_SL11		(1 << 11)
+#define CR_SL10		(1 << 10)
+#define CR_SL9		(1 << 9)
+#define CR_SL8		(1 << 8)
+#define CR_SL7		(1 << 7)
+#define CR_SL6		(1 << 6)
+#define CR_SL5		(1 << 5)
+#define CR_SL4		(1 << 4)
+#define CR_SL3		(1 << 3)
+#define CR_SL2		(1 << 2)
+#define CR_SL1		(1 << 1)
+#define CR_EN		(1 << 0)	/* transmit enable */
 
 /*
  * status register bits. P49
@@ -229,6 +229,7 @@
 	/* AC'97 */
 	struct mutex		ac97_sem;
 	struct snd_ac97_bus	*ac97_bus;
+	struct snd_ac97		*ac97;
 
 	u32			maincr;
 	spinlock_t		lock;